私のコードは多くのスレッド間で共有されるデータ構造を持っていますが、私はを使用してLinkedBlockingQueue
いるので、次のコードでは同期が必要ですか?
public synchronized String getDirectory(){
return directoryArray.poll();
}
私のコードは多くのスレッド間で共有されるデータ構造を持っていますが、私はを使用してLinkedBlockingQueue
いるので、次のコードでは同期が必要ですか?
public synchronized String getDirectory(){
return directoryArray.poll();
}
いいえ、何のメリットもなく、アプリケーションの速度が低下するだけです。の実装でLinkedBlockingQueue#poll()
は、再入可能ロックを使用した同期メカニズムがすでに実装されています。
public E poll() {
final AtomicInteger count = this.count;
if (count.get() == 0)
return null;
E x = null;
int c = -1;
final ReentrantLock takeLock = this.takeLock;
takeLock.lock();
try {
if (count.get() > 0) {
x = dequeue();
c = count.getAndDecrement();
if (c > 1)
notEmpty.signal();
}
} finally {
takeLock.unlock();
}
if (c == capacity)
signalNotFull();
return x;
}
追加の同期が必要だとは思いません。ドキュメントによると-リンク
BlockingQueueの実装はスレッドセーフです。すべてのキューイングメソッドは、内部ロックまたは他の形式の同時実行制御を使用して、アトミックにその効果を実現します。ただし、一括収集操作addAll、containsAll、retainAll、およびremoveAllは、実装で特に指定されていない限り、必ずしもアトミックに実行されるとは限りません。したがって、たとえば、cの要素の一部のみを追加した後、addAll(c)が失敗する(例外をスローする)可能性があります。
LinkedBlockingQueue
を実装しているためBlockingQueue
、この文書化された動作がそれに適用されます。
BlockingQueue
実装はスレッドセーフです。すべてのキューイングメソッドは、内部ロックまたは他の形式の同時実行制御を使用して、アトミックにその効果を実現します。
これは、追加の同期が必要ないことを意味します。