Punkt polega na synchronizacji czegoś, co zwykle jest dość asynchroniczne - jeden wątek umieszcza element w kolejce, podczas gdy inny próbuje go pobrać.
W rzeczywistości SynchronousQueue
tak naprawdę nie jest kolejką. Nie ma pojemności, nie ma pamięci wewnętrznej. Pozwala tylko na pobieranie z kolejki, gdy inny proces próbuje obecnie umieścić w kolejce.
Przykład:
Proces A próbuje umieścić w kolejce. To blokuje na razie. Proces B próbuje pobrać z kolejki. Ponieważ ktoś próbuje umieścić, przedmiot jest przenoszony z punktu A do punktu B, a oba są odblokowane.
Proces B próbuje pobrać z kolejki, ale nikt nie próbuje go umieścić. Więc B jest teraz zablokowany. Proces A teraz chce umieścić przedmiot. Teraz przedmiot zostaje przeniesiony do B, a A i B nie są już blokowane.
O blokowaniu:
Wdrożenie Sun/Oracle JRE nie wykorzystać odpytywanie zamiast czekać/zawiadomić wzorzec jeśli nie czasowego operacji (jak „próby przejęcia przez 1 sekundę”). Ma to sens: okresowo ponawia próbę, aż do upływu czasu. Kiedy wykonujesz operację niezwiązaną z czasem (np. "Weź, bez względu na to, jak długo to potrwa", używa ona park
, która ponownie się budzi, jeśli sytuacja uległa zmianie.W obu sytuacjach jeden z twoich rdzeni będzie ciągle zajęty obracaniem pętli. for (;;)
oznacza "ponawiam próbę w nieskończoność" w tym przypadku, nie oznacza "ciągłego wirowania"
To jest podstawa algorytmów wolnych od blokady - zauważ, że wirowanie jest wykonywane tylko wtedy, gdy jest coś do przeniesienia. transfer jest zakończony lub jeśli nie ma nic do zrobienia, metoda zwraca. – assylias
@assylias: W większości części 'TransferQueue.transferer' występuje' continue', a nie 'return'. W niektórych przypadkach jest powrót, w którym sprawa Nie mam pojęcia, co dzieje się z kelnerami i kiedy/jak restartują – Jim