SynchronousQueue
是一种非常特殊的队列——它在Queue
.
因此,您可能仅在需要特定语义的特殊情况下才需要它,例如,单线程任务而不排队进一步的请求。
使用的另一个原因SynchronousQueue
是性能。的实现SynchronousQueue
似乎已经过高度优化,所以如果您只需要一个集合点(例如Executors.newCachedThreadPool()
,消费者是“按需”创建的,因此队列项目不会累积),您可以通过使用SynchronousQueue
.
简单的综合测试表明,在简单的单生产者 - 单消费者场景中,双核机器吞吐量SynchronousQueue
约为 20 倍,LinkedBlockingQueue
队列ArrayBlockingQueue
长度 = 1。当队列长度增加时,它们的吞吐量上升并几乎达到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
}
}
这是我机器上的结果:
![在此处输入图像描述](https://i.stack.imgur.com/UuEpU.png)