gpt4 book ai didi

java - BlockingQueue : What are the differences between SynchronousQueue and LinkedBlockingQueue 的实现

转载 作者:IT老高 更新时间:2023-10-28 21:00:21 29 4
gpt4 key购买 nike

我看到了 BlockingQueue 的这些实现,无法理解它们之间的区别。到目前为止我的结论:

  1. 我永远不需要 SynchronousQueue
  2. LinkedBlockingQueue 确保 FIFO,BlockingQueue 必须使用参数 true 创建才能使其 FIFO
  3. SynchronousQueue 破坏了大多数集合方法(包含、大小等)

那么我什么时候需要SynchronousQueue?此实现的性能是否优于 LinkedBlockingQueue

为了让它更复杂......为什么 Executors.newCachedThreadPool 使用 SynchronousQueue 而其他(Executors.newSingleThreadExecutorExecutors.newFixedThreadPool ) 使用 LinkedBlockingQueue?

编辑

第一个问题解决了。但是我仍然不明白为什么 Executors.newCachedThreadPool 使用 SynchronousQueue 而其他(Executors.newSingleThreadExecutorExecutors.newFixedThreadPool)使用 LinkedBlockingQueue?

我得到的是,使用 SynchronousQueue,如果没有空闲线程,生产者将被阻塞。但是由于线程的数量实际上是无限的(如果需要,将创建新的线程),这永远不会发生。那么为什么要使用 SynchronousQueue?

最佳答案

SynchronousQueue是一种非常特殊的队列——它在Queue的接口(interface)后面实现了一种集合方式(生产者等待消费者准备好,消费者等待生产者准备好)。 .

因此,您可能仅在需要特定语义的特殊情况下才需要它,例如 Single threading a task without queuing further requests .

使用 SynchronousQueue 的另一个原因是性能。 SynchronousQueue的实现似乎已经过高度优化,所以如果您只需要一个集合点(如 Executors.newCachedThreadPool() 的情况,消费者是“按需”创建的,因此队列项目不会累积),您可以通过使用 SynchronousQueue 获得性能提升.

简单的综合测试表明,在简单的单生产者-单消费者场景中,双核机器吞吐量为SynchronousQueueLinkedBlockingQueue 的吞吐量高约 20 倍和 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
}
}

这是我机器上的结果:

enter image description here

关于java - BlockingQueue : What are the differences between SynchronousQueue and LinkedBlockingQueue 的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5102570/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com