SynchronousQueue
は非常に特別な種類のキューですQueue
。 .
したがって、特定のセマンティクスが必要な特別な場合にのみ必要になる場合があります。
使用するもう 1 つの理由SynchronousQueue
は、パフォーマンスです。の実装はSynchronousQueue
非常に最適化されているようです。そのため、ランデブー ポイント以外のものが必要ない場合 ( の場合のようにExecutors.newCachedThreadPool()
、コンシューマーが「オンデマンド」で作成されるため、キュー アイテムが蓄積されません)、次のことができます。を使用してパフォーマンスを向上させSynchronousQueue
ます。
単純な合成テストは、単純な単一の生産者と単一の消費者のシナリオで、デュアルコア マシンのスループットが、キューの長さ = 1 の場合SynchronousQueue
のスループットの ~20 倍高いことを示しています。キューの長さが増加すると、スループットは上昇し、ほぼ. これは、他のキューと比較して、マルチコア マシンでの同期オーバーヘッドが低いことを意味します。しかし、繰り返しになりますが、これは、ランデブー ポイントが に偽装される必要がある特定の状況でのみ重要になります。LinkedBlockingQueue
ArrayBlockingQueue
SynchronousQueue
SynchronousQueue
Queue
編集:
ここにテストがあります:
public class Test {
static ExecutorService e = Executors.newFixedThreadPool(2);
static int N = 1000000;
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
int length = (i == 0) ? 1 : i * 5;
System.out.print(length + "\t");
System.out.print(doTest(new LinkedBlockingQueue<Integer>(length), N) + "\t");
System.out.print(doTest(new ArrayBlockingQueue<Integer>(length), N) + "\t");
System.out.print(doTest(new SynchronousQueue<Integer>(), N));
System.out.println();
}
e.shutdown();
}
private static long doTest(final BlockingQueue<Integer> q, final int n) throws Exception {
long t = System.nanoTime();
e.submit(new Runnable() {
public void run() {
for (int i = 0; i < n; i++)
try { q.put(i); } catch (InterruptedException ex) {}
}
});
Long r = e.submit(new Callable<Long>() {
public Long call() {
long sum = 0;
for (int i = 0; i < n; i++)
try { sum += q.take(); } catch (InterruptedException ex) {}
return sum;
}
}).get();
t = System.nanoTime() - t;
return (long)(1000000000.0 * N / t); // Throughput, items/sec
}
}
そして、これが私のマシンでの結果です:
