web-dev-qa-db-ja.com

LinkedBlockingQueueのinsertメソッドとremoveメソッドはスレッドセーフですか?

2つの異なるスレッド間でLinkedBlockingQueueを使用しています。 1つのスレッドはaddを介してデータを追加し、もう1つのスレッドはtakeを介してデータを受信します。

私の質問は、addtakeへのアクセスを同期する必要がありますか。 LinkedBlockingQueueの挿入および削除メソッドはスレッドセーフですか?

52
Steve Kuo

はい。 ドキュメント から:

「BlockingQueue実装はスレッドセーフです。すべてのキューイングメソッドは、内部ロックまたは他の形式の同時実行制御を使用してアトミックに効果を達成します。そのため、たとえば、cの一部の要素のみを追加した後にaddAll(c)が失敗(例外をスロー)する可能性があります。」

54

はい、BlockingQueueメソッドadd()およびtake()はスレッドセーフですただし違いがあります

add ()およびtake()メソッドは、2つの異なるReentrantLockオブジェクトを使用します。

_add(_)メソッドは

_private final ReentrantLock putLock = new ReentrantLock();
_

take()メソッドは

_private final ReentrantLock takeLock = new ReentrantLock();
_

したがって、add()メソッドへの同時アクセスは同期されます。同様に、take()メソッドへの同時アクセスはsynchronizedです。

ただし、add()およびtake()メソッドへの同時アクセスはsynchronizedではありません。これらは2つの異なるロックオブジェクトを使用しているためです(キューがいっぱいのEdge条件中を除く/空)。

12
Amrish Pandey

単にはい、それは間違いなくスレッドセーフです。そうでなければ、ThreadPoolExecutorの要素を格納するための候補としては資格がありません。

BlockingQueueの同時実行性を心配することなく、要素を追加および取得するだけです。

0
Java Guru