Circular Bounded Buffer no Pharo Smalltalk

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 ! !

Deixe um comentário