29

我想我应该从

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

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

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

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

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

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

4

3 回答 3

39

BlockingQueue如果您想限制某种请求,有限的容量也很有帮助。使用无界队列,生产者可以远远领先于消费者。这些任务最终会被执行(除非有太多以至于它们会导致OutOfMemoryError),但生产者可能早就放弃了,所以努力就白费了。

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


关于修改后的问题,我将其解释为“什么是在池中保存对象的好集合?”

无界LinkedBlockingQueue是许多池的不错选择。但是,根据您的池管理策略,aConcurrentLinkedQueue也可能有效。

在池应用程序中,阻塞“放置”是不合适的。控制队列的最大大小是池管理器的工作——它决定何时为池创建或销毁资源。池的客户端从池中借用和归还资源。添加新对象,或将以前借用的对象返回到池中应该是快速、非阻塞的操作。因此,有限容量队列对于池来说不是一个好的选择。

另一方面,当从池中检索对象时,大多数应用程序都希望等到资源可用。至少暂时阻塞的“获取”操作比“忙等待”(重复轮询直到资源可用)效率高得多。在这种情况下,这LinkedBlockingQueue是一个不错的选择。借款人可以无限期地阻止take,或限制它愿意阻止的时间poll

一个不太常见的情况是客户端根本不愿意阻塞,但如果池为空,它有能力为自己创建资源。在这种情况下,aConcurrentLinkedQueue是一个不错的选择。这是一个灰色地带,尽可能多地共享资源(例如内存)会很好,但速度更为重要。在更坏的情况下,这会退化为每个线程都有自己的资源实例;那么不必费心尝试在线程之间共享会更有效。

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

于 2008-12-11T06:20:37.593 回答
4

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

于 2008-12-11T04:40:50.713 回答
3

它是一种Queue额外支持以下操作的实现

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

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

如果您需要上述功能,那么您的实施将遵循您的要求,Queue然后使用Blocking Queue

于 2017-08-21T07:00:53.317 回答