Mam klasyczny problem wątku przesuwającego zdarzenia do przychodzącej kolejki drugiego wątku. Tylko tym razem jestem bardzo zainteresowany osiągami. Co chcę osiągnąć to:Kolejka współbieżna i blokująca w Javie
- Chcę mieć równoczesny dostęp do kolejki, producent popycha, odbiornik wyskakuje.
- Gdy kolejka jest pusta, chcę, aby konsument zablokował się w kolejce, czekając na producenta.
Mój pierwszy pomysł polegał na użyciu LinkedBlockingQueue
, ale wkrótce zdałem sobie sprawę, że nie jest to współbieżne, a wydajność uległa pogorszeniu. Z drugiej strony używam teraz ConcurrentLinkedQueue
, ale nadal płacę za każdą publikację kosztami: wait()
/notify()
. Ponieważ konsument, po znalezieniu pustej kolejki, nie blokuje, muszę zsynchronizować i wait()
na zamku. Z drugiej strony producent musi uzyskać tę blokadę i notify()
przy każdej publikacji. Ogólny wynik jest taki, że płacę kosztem sycnhronized (lock) {lock.notify()}
w każdej publikacji, nawet jeśli nie jest to konieczne.
To, co w tym przypadku jest potrzebne, to kolejka blokująca i współbieżna. Wyobrażam sobie operację push()
, która działa tak jak w ConcurrentLinkedQueue
, z dodatkowym notify()
obiektem, gdy element pchany jest pierwszy na liście. Takie sprawdzanie uważam za już istniejące w ConcurrentLinkedQueue
, ponieważ pchanie wymaga połączenia z kolejnym elementem. Tak więc byłoby to znacznie szybsze niż synchronizacja za każdym razem na zewnętrznej blokadzie.
Czy coś takiego jest dostępne/rozsądne?
Dlaczego uważasz, że java.util.concurrent.LinkedBlockingQueue nie jest współbieżne? Myślę, że jest idealnie równoległy, widząc jego javadoc i kod źródłowy. Ale nie mam pojęcia o wydajności. – Rorick
Zobacz także http://stackoverflow.com/questions/1301691/java-queue-implementations-which-one – Vadzim