5

Próbowałem przeczytać implementację Synchronous Queue
To nie jest takie proste dla mnie. Wydaje się, że używa ona połączonej listy, w której każdy węzeł jest powiązany z wątkiem.
Część rdzenia używa pętli spinu oczekującej na umieszczenie zadań w kolejce.
Zastanawiam się, dlaczego używa się pętli spinów zamiast czegoś podobnego do wait/notify?
W ten sposób jeden z rdzeni zniknął z powodu tej stałej pętli spinu, prawda?
Próbuję zrozumieć ten punkt i uzyskać chropowatą zrozumienie projektu synchronicznego kolejkiPróba zrozumienia mechanizmu kolejki synchronicznej

UPDATE
Co mnie niepokojące jest również to, jak nici kelner start/stop.

+0

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

+0

@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

Odpowiedz

4

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"

+0

Myślę, że nie ma faktycznego blokowania. Mam na myśli, że część blokująca jest realizowana za pośrednictwem pętla spinów.Ta pętla "zjada" cykle procesora. Dlaczego nie blokowanie zostało zaimplementowane za pomocą jakiejś formy 'wait' lub' sleep'? – Jim

+0

Mylisz się, więc ;-) Jest blokowanie. Z tego powodu połączony dokument API otwiera się wraz z zdaniem '' Kolejka blokująca, w której każda operacja wstawiania musi czekać na odpowiednią operację usuwania przez inny wątek i na odwrót. "' –

+1

Ale cytujesz już javadoc.I już wspomniałem że próbowałem zrozumieć implementację, w której znalazłem 'for (;;) {' w implementacji 'transfer'. – Jim