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

Vai*_*ble 23 java queue

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

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

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

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

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

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

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

eri*_*son 34

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

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


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

LinkedBlockingQueue对于许多游泳池来说,无界是一个不错的选择.但是,根据您的池管理策略,ConcurrentLinkedQueue也可以使用.

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

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

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

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