Circular Bounded Buffer é uma estrutura de dados que usa a disciplina FIFO (First In First Out). É uma fila. Pode ser usada compartilhada com vários threads. Bloqueia os threads que tentem remover elemento de uma fila vazia ou adicionar elementos a uma fila com sua capacidade esgotada.
A interface pública inclui os seguintes métodos:
- next
- nextPut:
- isEmpty
- isFull
next
Remove o elemento no início da fila. Se a fila estiver vazia coloca o thread que tentou remover o elemento em espera.
nextPut:
Adiciona um elemento ao final da fila. Se a fila estiver cheia (o número de elementos é igual à sua capacidade) coloca o thread que tentou adicionar o elemento em espera.
isEmpty
Testa se a fila está vazia.
isFull
Testa se a fila está cheia.
Demo
O “testes” abaixo mostram no Transcript a evolução da fila “acossada” por dois threads.
File out
Abaixo segue o file-out:
'From Pharo9.0.0 of 31 August 2021 [Build information: Pharo-9.0.0+build.1545.sha.c99fdae9aff16a6eca9422d4ab57ffb7e7237b2d (64 Bit)] on 23 September 2021 at 9:42:04.843954 am'!
Object subclass: #CircularBoundedBuffer
instanceVariableNames: 'capacity circularArray size first last monitor empty full'
classVariableNames: ''
package: 'TankBattle-BoundedBuffer'!
!CircularBoundedBuffer methodsFor: 'printing' stamp: 'chicoary 9/18/2021 23:20'!
printOn: stream
stream print: ((1 to: size) collect: [ :n | circularArray atWrap: first + n - 1 ])! !
!CircularBoundedBuffer methodsFor: 'initialization' stamp: 'chicoary 9/18/2021 23:20'!
initialize
size := 0.
first := 1.
last := 0.
empty := Semaphore new.
full := Semaphore new.
monitor := Monitor new! !
!CircularBoundedBuffer methodsFor: 'as yet unclassified' stamp: 'chicoary 9/18/2021 23:20'!
nextPut: anObject
[ size = capacity ] whileTrue: [ full wait ].
monitor critical: [
last := last \\ capacity + 1.
circularArray at: last put: anObject.
size := size + 1.
].
empty signal.
^ anObject
! !
!CircularBoundedBuffer methodsFor: 'as yet unclassified' stamp: 'chicoary 9/18/2021 23:20'!
next
| anObject |
[ size = 0 ] whileTrue: [ empty wait ].
monitor critical: [
anObject := circularArray at: first.
first := first \\ capacity + 1.
size := size - 1.
].
full signal.
^ anObject! !
!CircularBoundedBuffer methodsFor: 'as yet unclassified' stamp: 'chicoary 9/18/2021 23:20'!
setCapacity: anInteger
capacity := anInteger.
circularArray := Array new: anInteger! !
!CircularBoundedBuffer methodsFor: 'testing' stamp: 'chicoary 9/23/2021 09:21'!
isFull
^ monitor critical: [ size = capacity ]! !
!CircularBoundedBuffer methodsFor: 'testing' stamp: 'chicoary 9/22/2021 20:54'!
isEmpty
^ monitor critical: [ size = 0 ]! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
CircularBoundedBuffer class
instanceVariableNames: ''!
!CircularBoundedBuffer class methodsFor: 'as yet unclassified' stamp: 'chicoary 9/18/2021 23:20'!
capacity: anInteger
^ self new setCapacity: anInteger ! !