2013-04-13 11 views
9

Podczas czytania kodu źródłowego ArrayBlockingQueue znalazłem komentarz wyjaśniający, że używa „klasyczny algorytm dwóch warunek znaleźć w każdym podręczniku”:dlaczego współbieżności sterowania wykorzystuje klasyczne dwa warunek algorytm

/* 
* Concurrency control uses the classic two-condition algorithm 
* found in any textbook. 
*/ 

/** Main lock guarding all access */ 
private final ReentrantLock lock; 
/** Condition for waiting takes */ 
private final Condition notEmpty; 
/** Condition for waiting puts */ 
private final Condition notFull; 

Dlaczego korzysta z klasycznego algorytmu dwuwarunkowego (notEmpty, notFull)?

+10

pozwala ona tylko obudzić wątki zainteresowanych cokolwiek się stało. Na przykład wątek próbujący "wziąć" z pustej kolejki jest zainteresowany tylko tym, że kolejka nie jest pusta (jest coś do zrobienia), ale nie dba o to, że kolejka nie jest pełna. – assylias

+0

To jest miła * odpowiedź * :) –

+0

Twoje pytanie sugeruje, że nie zgadzasz się lub nie rozumiesz decyzji autora. Jakie inne podejście wiesz, że mógł wybrać zamiast tego? – seh

Odpowiedz

1

Masz już dobry komentarz. Tylko jako uzupełnienie.

ArrayBlockingQueue to klasa zależna od stanu zależna od stanu. Oznacza to, że ta klasa ma operacje, które można wykonać tylko z pewnymi warunkami wstępnymi.

Wątki pisarza będą czekać tylko, jeśli warunek wstępny (notFull) jest fałszywy.

// Jeśli kolejka jest pełna, pisarz musi poczekać.
// Atomowa zwalnia blokadę i czeka na sygnał (notFull.signal() uruchomiony przez czytnik).
while (count == items.length)
notFull.await();

Dla czytelników koncepcja jest identyczna, ale z użyciem warunku notEmpty.

// Jeśli kolejka jest pusta, czytnik musi poczekać.
// Atomowa zwalnia blokadę i czeka na sygnał (notEmpty.signal() wystrzelony przez pisak).
natomiast (liczba == 0)
notEmpty.await();

Kiedy wątek budzi się wtedy trzeba 2 główne rzeczy:
1 - Get blokadę
2 - Re-Test kondycji

Powiązane problemy