阻塞队列 - 阻塞排水管To() 方法

2022-09-01 07:28:02

BlockingQueue有一个名为referTo()的方法,但它没有被阻塞。我需要一个要阻止的队列,但也能够在单个方法中检索排队的对象。

Object first = blockingQueue.take();

if ( blockingQueue.size() > 0 )
    blockingQueue.drainTo( list );

我想上面的代码会起作用,但我正在寻找一个优雅的解决方案。


答案 1

您指的是 JavaDoc 中的注释吗:

此外,如果在操作过程中修改了指定的集合,则此操作的行为未定义。

我相信这是指您的示例中的集合:list

blockingQueue.drainTo(list);

这意味着您无法在从 中抽取的同时进行修改。但是,阻塞队列在内部同步,以便在调用时,put 和(请参阅下面的注释)get 将阻塞。如果它不这样做,那么它就不是真正的线程安全。您可以查看源代码,并验证该源代码对于阻塞队列本身是否为线程安全。listblockingQueuelistdrainTodrainTo

或者,您的意思是,当您调用它时,您希望它阻塞,直到至少有一个对象被添加到队列中?在这种情况下,除了以下之外,您别无选择:drainTo

list.add(blockingQueue.take());
blockingQueue.drainTo(list);

以阻止,直到添加了一个或多个项目,然后将整个队列排出到集合中。list

注意:从 Java 7 开始,一个单独的锁用于 get 和 put。现在允许在 drainTo 期间执行看跌操作(以及许多其他看跌操作)。


答案 2

如果你碰巧使用Google Guava,有一个漂亮的Queets.drain()方法。

将队列排空为 ,但如果请求的元素不可用,它将等待它们直到指定的超时。BlockingQueue.drainTo(Collection, int)numElements


推荐