2010-04-23 12 views

Antwort

45

Ja. Von the docs:..

„Blocking Implementierungen Thread-sichere Alle Warteschlangen Methoden ihre Effekte erzielen atomar interne Schlösser oder andere Formen der Nebenläufigkeitssteuerung Verwendung jedoch die Masse Sammlung Operationen addAll, containsAll, retainAll und removeAll werden nicht unbedingt atomisch durchgeführt, es sei denn, in einer Implementierung wird angegeben, so ist es beispielsweise möglich, dass addAll (c) nachfehlschlägt (Ausnahme auslöst)Hinzufügen nur einiger Elemente in c. "

+0

ist es nicht wirklich. Nein, nicht, wenn Sie nur add und take verwenden, aber wenn Sie eine Massenoperation verwenden würden, müssten Sie sie statt einfach nur "Ja" synchronisieren? Oder lese ich das Dokument falsch? – cproinger

+0

@cproinger, nein, du musst es nie synchronisieren, solange du bereit bist mit 'addAll' umzugehen, das nach dem Hinzufügen einer Teilmenge der Elemente (oder ähnlichem) eine Ausnahme auslöst. Es hängt davon ab, wie Sie Thread-sicher definieren. Sie haben Recht, dass die Bulk-Methoden keine Atomizitätsgarantie haben. –

+0

Ist 'remove' auch threadsicher? – q126y

8

Ja, BlockingQueue Methoden add() und take() sind Thread-sicher aber mit einem Unterschied.

add() und take() Methode verwendet 2 verschiedene ReentrantLock Objekte.

add() Methode verwendet

private final ReentrantLock putLock = new ReentrantLock(); 

take() Methode verwendet

private final ReentrantLock takeLock = new ReentrantLock(); 

Daher wird der gleichzeitige Zugriff auf add() Verfahren synchronisiert. In ähnlicher Weise ist der gleichzeitige Zugang zu take() Methode .

aber gleichzeitiger Zugriff auf add() und take() Methode ist nicht synchronized da sie 2 verschiedene Sperrobjekte verwendet werden (außer während der Randbedingung der Warteschlange voll/leer).

+3

Diese Antwort macht eine gültige Beobachtung, aber vermisst, dass die Implementierer von LinkedBlockingQueue dieses Problem erkannt und adressiert. Details hier: http://stackoverflow.com/questions/26543807/is-blockingqueue-completely-thread-safe-in-java/26543940#26543940 –

+0

Ja, ich stimme zu. LInkedBlockingQueue bietet bessere Gleichzeitigkeit als ArrayBlockingQueue und behält die Threadsicherheit bei, indem nur die Kantenbedingung synchronisiert wird. Methoden zum Einfügen und Entfernen wurden nur für Edge-Cases intelligent synchronisiert –

+0

Diese Antwort ist falsch. 'add' und' take' sind Thread-sicher und können gleichzeitig ohne zusätzliche Synchronisation verwendet werden. – ens

0

Einfach ja, es ist definitiv threadsicher, sonst hätte es nicht als ein Kandidat zum Speichern von Element für ThreadPoolExecutor qualifiziert.

Einfach Element hinzufügen und abrufen, ohne sich Gedanken über Nebenläufigkeit für BlockingQueue zu machen.

Verwandte Themen