您应该在哪里使用BlockingQueue实现而不是简单队列实现?

我想我会重新提出我的问题

您应该在哪里使用BlockingQueue实现而不是简单队列实现?

BlockingQueue优于队列实现的优点/缺点是什么,考虑速度,并发或其他属性等方面,例如访问最后一个元素的时间。

我使用过这两种队列。 我知道Blocking Queue通常用于并发应用程序。 我正在编写简单的ByteBuffer池,我需要一些ByteBuffer对象的占位符。 我需要最快,线程安全的队列实现。 甚至像ArrayList这样的List实现也具有元素的持续访问时间。

任何人都可以讨论BlockingQueue与Queue vs List实现的优缺点吗?

目前我使用ArrayList来保存这些ByteBuffer对象。

我应该使用哪种数据结构来保存这些对象?

如果要限制某种请求,有限容量的BlockingQueue也很有用。 通过无限制的队列,生产者可以远远领先于消费者。 最终将执行任务(除非它们导致OutOfMemoryError太多),但生产者可能早已放弃,因此浪费了精力。

在这样的情况下,最好向潜在的生产者发出队列已满的信号,并在发生故障时迅速放弃。 例如,生产者可能是一个Web请求,用户不想等待太长时间,即使它在等待时不会消耗很多CPU周期,它也会耗尽有限的资源,如套接字和一些内存。 放弃将使排队的任务更有机会及时完成。


关于修正后的问题,我将其解释为“在游泳池中保存物品有什么好处?”

无界的LinkedBlockingQueue是许多池的不错选择。 但是,根据您的池管理策略, ConcurrentLinkedQueue也可以工作。

在池化应用程序中,阻塞“put”是不合适的。 控制队列的最大大小是池管理器的工作 – 它决定何时创建或销毁池的资源。 池的客户端从池中借用和返回资源。 添加新对象或将先前借用的对象返回到池应该是快速,无阻塞的操作。 因此,有界容量队列不是池的好选择。

另一方面,从池中检索对象时,大多数应用程序都希望等到资源可用。 至少暂时阻止的“接受”操作比“忙等待”更有效 – 重复轮询直到资源可用。 在这种情况下, LinkedBlockingQueue是一个不错的选择。 借款人可以无限制地阻止,或限制其愿意通过poll阻止的时间。

当客户端根本不愿意阻塞时,这种情况不太常见,但如果池为空,则能够为自己创建资源。 在这种情况下, ConcurrentLinkedQueue是一个不错的选择。 这是一个灰色区域,尽可能多地共享资源(例如,内存),但速度更重要。 在更糟糕的情况下,这会退化为具有自己的资源实例的每个线程; 那么不打算尝试在线程之间共享会更有效率。

这两个集合在并发应用程序中提供了良好的性能和易用性。 对于非并发应用程序, ArrayList很难被击败。 即使对于动态增长的集合, LinkedList的每元素开销也允许具有一些空插槽的ArrayList在内存方面保持竞争力。

您会在multithreading情况下看到BlockingQueue 。 例如,如果要使用构造函数创建一个,则需要传入BlockingQueue作为参数来创建ThreadPoolExecutor 。 根据您传入的队列类型,执行程序可能采取不同的行为。

BlockingQueue对于序列化彼此依赖的并行操作也很有用。

为了给出一个具体的(尽管有点武断)示例, 这里是一个实时患者队列Web应用程序的并行测试,其中callInPatient()需要与registerPatientToAppointment()并行启动,但需要等到registerPatientToAppointment()完成之前执行callPatientInAtDoctorsOffice()

 public class ClinicPatientQueueAppTest extends ParallelTest { private static final BlockingQueue WAIT_FOR_REGISTRATION_QUEUE = new ArrayBlockingQueue(2); @Test public void callInPatient() { loginToDoctorsOffice("user", "password"); waitUntilRegistrationCompleted(); // <-- callPatientInAtDoctorsOffice(); } @Test public void registerPatientToAppointment() { registerPatientAtRegistrationKiosk("Patient Peter"); notifyRegistrationCompleted(); // <-- } private void waitUntilRegistrationCompleted() { WAIT_FOR_REGISTRATION_QUEUE.take(); } private void notifyRegistrationCompleted() { WAIT_FOR_REGISTRATION_QUEUE.put(this); } } 

它是一个Queue实现,另外支持这些操作

检索元素时等待队列变为非空状态,

等待存储元素时队列中的空间可用。

如果您需要以上function,则Queue实现将遵循以下function,然后使用Blocking Queue