我想我将重新提出我的问题
您应该在哪里使用BlockingQueue实现而不是Simple Queue实现?
至
考虑到速度,并发性或其他属性(例如,访问最后一个元素的时间)等方面,BlockingQueue与Queue实现相比的优缺点是什么?
我已经使用了两种队列。我知道阻塞队列通常在并发应用程序中使用。我正在编写简单的ByteBuffer池,其中需要一些用于ByteBuffer对象的占位符。我需要最快的线程安全队列实现。甚至还有诸如ArrayList之类的List实现,它们对元素的访问时间是恒定的。
谁能讨论BlockingQueue vs Queue vs List实现的优缺点?
目前,我已经使用ArrayList来保存这些ByteBuffer对象。
我应使用哪种数据结构来保存这些对象?
BlockingQueue如果您想限制某种请求,则容量有限也很有帮助。有了无限的队列,生产者可以远远领先于消费者。最终将执行任务(除非有太多导致它们引起的任务OutOfMemoryError),但是生产者可能早就放弃了,因此浪费了精力。
BlockingQueue
OutOfMemoryError
在这种情况下,最好向可能的生产者发信号通知队列已满,并在出现故障时迅速放弃。例如,生产者可能是一个Web请求,用户不想等待太久,即使等待时它不会消耗很多CPU周期,它也会消耗有限的资源,例如套接字和一些内存。放弃将使已经排队的任务有更好的机会及时完成。
关于修改后的问题,我将其解释为“将对象保存在池中的好集合是什么?”
无边界LinkedBlockingQueue是许多池的不错选择。但是,根据您的池管理策略,a ConcurrentLinkedQueue也可以工作。
LinkedBlockingQueue
ConcurrentLinkedQueue
在池应用程序中,阻塞的“放置”是不合适的。控制队列的最大大小是池管理器的工作,它决定何时为池创建或销毁资源。池的客户从池中借用并返回资源。添加新对象或将先前借用的对象返回到池中应该是快速的非阻塞操作。因此,有限容量队列不是池的理想选择。
另一方面,从池中检索对象时,大多数应用程序都希望等到资源可用为止。至少暂时阻止的“获取”操作比“忙碌的等待”要有效得多- 重复轮询直到资源可用。该LinkedBlockingQueue是个不错的选择在这种情况下。借款人可以无限期冻结take,也可以限制愿意冻结的时间poll。
take
poll
一个不太普遍的情况,即客户端根本不愿意阻塞,但是如果池为空,则可以为自己创建资源。在这种情况下,a ConcurrentLinkedQueue是一个不错的选择。这是一个灰色区域,在该区域中尽可能多地共享资源(例如,内存)会很不错,但是速度更为重要。在最坏的情况下,这会退化为每个线程都有自己的资源实例;那么不麻烦尝试在线程之间共享就更有效了。
这两个集合都提供了良好的性能,并且在并发应用程序中易于使用。对于非并行应用程序,an ArrayList很难被击败。即使对于动态增长的集合,a的每个元素开销也LinkedList允许ArrayList带有一些空插槽的容器在内存方面保持竞争力。
ArrayList
LinkedList