LinkedBlockingQueue vs ConcurrentLinkedQueue

我的问题与前面提出的这个问题有关。在我使用队列在生产者和消费者线程之间进行通信的情况下,人们通常会建议使用 or ?LinkedBlockingQueueConcurrentLinkedQueue

使用一个相对于另一个的优点/缺点是什么?

从 API 的角度来看,我可以看到的主要区别是 a 可以选择有界。LinkedBlockingQueue


答案 1

对于生产者/消费者线程,我不确定这是否是一个合理的选择 - 它没有实现,这是生产者/消费者队列IMO的基本接口。你必须打电话,如果你没有找到任何东西,请稍等片刻,然后再次轮询等等......导致新物品进来时延迟,空置时效率低下(由于不必要地从睡眠中醒来)。ConcurrentLinkedQueueBlockingQueuepoll()

从 BlockingQueue 的文档:

BlockingQueue实现被设计为主要用于生产者-消费者队列

我知道它并没有严格地说只应该将阻塞队列用于生产者 - 消费者队列,但即便如此......


答案 2

这个问题应该得到更好的答案。

Java基于Maged M. Michael和Michael L. Scott的着名算法,用于非阻塞无锁队列。ConcurrentLinkedQueue

“非阻塞”在这里作为争用资源(我们的队列)的术语意味着,无论平台的调度程序做什么,比如中断线程,或者如果有问题的线程太慢,其他争夺相同资源的线程仍然能够取得进展。例如,如果涉及锁,则持有该锁的线程可能会中断,并且等待该锁的所有线程都将被阻止。Java中的固有锁(关键字)也可能对性能造成严重损害 - 例如,当涉及有偏见的锁定并且您确实存在争用时,或者在VM决定在旋转宽限期后“膨胀”锁并阻止争用线程之后...这就是为什么在许多上下文中(低/中争用的场景),对原子引用进行比较和集合可以更有效,这正是许多非阻塞数据结构正在做的事情。synchronized

Java不仅是非阻塞的,而且它具有生产者不会与消费者竞争的令人敬畏的属性。在单生产者/单一消费者场景(SPSC)中,这实际上意味着不会有争议可言。在多生产者/单一消费者的情况下,消费者不会与生产者竞争。当多个生产者尝试时,此队列确实存在争用,但根据定义,这是并发性。它基本上是一个通用且高效的非阻塞队列。ConcurrentLinkedQueueoffer()

至于它不是一个,好吧,阻塞一个线程等待队列是设计并发系统的一种非常可怕的方式。不要。如果你不知道如何在消费者/生产者场景中使用,那么只需切换到更高层次的抽象,比如一个好的演员框架。BlockingQueueConcurrentLinkedQueue


推荐