BlockingQueue

本文深入探讨了Java中BlockingQueue接口的特性,包括其基于队列的基本操作、容量限制、线程安全性以及如何用于生产者-消费者模式。重点介绍了BlockingQueue如何在不同场景下实现阻塞操作,以及其与并发集合的一致性效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BlockingQueue接口是在Queue基础上增加了两个操作<wbr style="line-height:25px">,</wbr>
<wbr style="line-height:25px"><span style="color:#003366; line-height:25px">两个操作是:检索元素时等待队列变为非空,以及存储元素时等待空间变得可用。<br style="line-height:25px"> (</span><span style="color:#000080; line-height:25px">试图向已满队列中放入元素会导致放入操作受阻塞,直到BlockingQueue里有新的空间才会被唤醒继续操作;<br style="line-height:25px"> 试图从空队列中检索元素将导致类似阻塞,直到BlocingkQueue进了新货才会被唤醒。</span><span style="color:#003366; line-height:25px">)</span><wbr style="line-height:25px"><br style="line-height:25px"><span style="color:#003366; line-height:25px"></span><span style="color:#993300; line-height:25px">BlockingQueue</span><span style="color:#003366; line-height:25px">不接受null元素。试图add、put或offer一个null元素时,<br style="line-height:25px"> 某些实现会抛出NullPointerException。null被用作指示poll操作失败的警戒值。<br style="line-height:25px"></span><span style="color:#993300; line-height:25px">BlockingQueue</span><span style="color:#003366; line-height:25px">可以是限定容量的。它在任意给定时间都可以有一个remainingCapacity,超出此容量,便无法无阻塞地put额外的元素。<br style="line-height:25px"> 没有任何内部容量约束的BlockingQueue总是报告Integer.MAX_VALUE的剩余容量。</span><br style="line-height:25px"> BlockingQueue实现主要用于生产者-使用者队列,但它另外还支持Collection接口。<br style="line-height:25px"> 因此,举例来说,使用remove(x)从队列中移除任意一个元素是有可能的。然而,这种操作通常不会有效执行,<br style="line-height:25px"> 只能有计划地偶尔使用,比如在取消排队信息时。<br style="line-height:25px"><span style="color:#000080; line-height:25px"></span><span style="color:#993300; line-height:25px">BlockingQueue</span><span style="color:#000080; line-height:25px">实现是线程安全的。</span><br style="line-height:25px"> 所有排队方法都可以使用内部锁定或其他形式的并发控制来自动达到它们的目的。<br style="line-height:25px"> 然而,<wbr style="line-height:25px"><span style="color:#000080; line-height:25px">大量的Collection操作(addAll、containsAll、retainAll和removeAll)没有必要自动执行<br style="line-height:25px"> (可能是空实现,它会抛出UnsupportOperationException),</span><br style="line-height:25px"><wbr style="line-height:25px">除非在实现中特别说明。因此,举例来说,在c中添加了的一些元素后,addAll(c)有可能失败(抛出一个异常)。<br style="line-height:25px"> BlockingQueue实质上不支持使用任何一种“close”或“shutdown”操作来指示不再添加任何项。<br style="line-height:25px"> 这种功能的需求和使用有依赖于实现的倾向。<br style="line-height:25px"> 例如,一种常用的策略是:对于生产者,插入特殊的end-of-stream或poison对象,并根据使用者获取这些对象的时间来对它们进行解释。<br style="line-height:25px"><span style="color:#000080; line-height:25px"><wbr style="line-height:25px">内存一致性效果:一致性效果:和其他并发集合一样。把一个元素放入到队列的线程的优先级高与对元素的访问和移除的线程<wbr style="line-height:25px">。</wbr></wbr></span><br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">注意1</wbr></span><wbr style="line-height:25px">:BlockingQueue可以安全地与多个生产者和多个使用者一起使用。<br style="line-height:25px"> 例1是基于典型的生产者-使用者场景的一个用例。<br style="line-height:25px"><span style="line-height:25px">注意2</span>:<wbr style="line-height:25px"><span style="color:#000080; line-height:25px">BlockingQueue实现是线程安全的<wbr style="line-height:25px">。<wbr style="line-height:25px">所有排队方法都可以使用内部锁定或其他形式的并发控制来自动达到它们的目的</wbr></wbr></span><span style="line-height:25px">。</span><br style="line-height:25px"><wbr style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">注意3</wbr></span>:在JDK5/6中,LinkedBlockingQueue和ArrayBlocingQueue等对象的poll(longtimeout,TimeUnitunit)存在内存泄露<br style="line-height:25px"> Leak的对象是AbstractQueuedSynchronizer.Node,<br style="line-height:25px"> 据称JDK5会在Update12里Fix,JDK6会在Update2里Fix。<br style="line-height:25px"> 更加详细参考<a target="_blank" rel="nofollow" href="http://sesame.javaeye.com/blog/428026" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">http://sesame.javaeye.com/blog/428026</a><wbr style="line-height:25px">和<a target="_blank" rel="nofollow" href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=2143840" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=2143840</a><wbr style="line-height:25px"></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
声明的接口
Public Methods
<nobr style="line-height:21px">abstract boolean</nobr> <nobr style="line-height:21px"><span style="line-height:21px; margin-right:2px"><a rel="nofollow" href="http://developer.android.com/reference/java/util/concurrent/BlockingQueue.html#add(E)" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">add</a></span>(E e)</nobr>
Inserts the specified element into this queue if it is possible to do so immediately without violating capacity restrictions, returning trueupon success and throwing an IllegalStateExceptionif no space is currently available.
<nobr style="line-height:21px">abstract boolean</nobr> <nobr style="line-height:21px"><span style="line-height:21px; margin-right:2px"><a rel="nofollow" href="http://developer.android.com/reference/java/util/concurrent/BlockingQueue.html#contains(java.lang.Object)" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">contains</a></span>(<a rel="nofollow" href="http://developer.android.com/reference/java/lang/Object.html" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">Object</a>o)</nobr>
Returns trueif this queue contains the specified element.
<nobr style="line-height:21px">abstract int</nobr> <nobr style="line-height:21px"><span style="line-height:21px; margin-right:2px"><a rel="nofollow" href="http://developer.android.com/reference/java/util/concurrent/BlockingQueue.html#drainTo(java.util.Collection&lt;?%20super%20E&gt;)" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">drainTo</a></span>(<a rel="nofollow" href="http://developer.android.com/reference/java/util/Collection.html" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">Collection</a>&lt;?superE&gt; c)</nobr>
Removes all available elements from this queue and adds them to the given collection.
移除此队列中所有可用的元素,并将它们添加到给定 collection 中。
<nobr style="line-height:21px">abstract int</nobr> <nobr style="line-height:21px"><span style="line-height:21px; margin-right:2px"><a rel="nofollow" href="http://developer.android.com/reference/java/util/concurrent/BlockingQueue.html#drainTo(java.util.Collection&lt;?%20super%20E&gt;,%20int)" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">drainTo</a></span>(<a rel="nofollow" href="http://developer.android.com/reference/java/util/Collection.html" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">Collection</a>&lt;?superE&gt; c, int maxElements)</nobr>
Removes at most the given number of available elements from this queue and adds them to the given collection.
最多从此队列中移除给定数量的可用元素,并将这些元素添加到给定 collection 中。
<nobr style="line-height:21px">abstract boolean</nobr> <nobr style="line-height:21px"><span style="line-height:21px; margin-right:2px"><a rel="nofollow" href="http://developer.android.com/reference/java/util/concurrent/BlockingQueue.html#offer(E,%20long,%20java.util.concurrent.TimeUnit)" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">offer</a></span>(E e, long timeout,<a rel="nofollow" href="http://developer.android.com/reference/java/util/concurrent/TimeUnit.html" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">TimeUnit</a>unit)</nobr>
Inserts the specified element into this queue, waiting up to the specified wait time if necessary for space to become available.
将指定的元素插入到此队列的尾部,如果没有可用空间,将等待指定的等待时间(如果有必要)。
<nobr style="line-height:21px">abstract boolean</nobr> <nobr style="line-height:21px"><span style="line-height:21px; margin-right:2px"><a rel="nofollow" href="http://developer.android.com/reference/java/util/concurrent/BlockingQueue.html#offer(E)" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">offer</a></span>(E e)</nobr>
Inserts the specified element into this queue if it is possible to do so immediately without violating capacity restrictions, returning trueupon success and falseif no space is currently available.
将指定的元素插入到此队列的尾部(如果可能),如果此队列已满,则立即返回。
<nobr style="line-height:21px">abstract E</nobr> <nobr style="line-height:21px"><span style="line-height:21px; margin-right:2px"><a rel="nofollow" href="http://developer.android.com/reference/java/util/concurrent/BlockingQueue.html#poll(long,%20java.util.concurrent.TimeUnit)" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">poll</a></span>(long timeout,<a rel="nofollow" href="http://developer.android.com/reference/java/util/concurrent/TimeUnit.html" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">TimeUnit</a>unit)</nobr>
Retrieves and removes the head of this queue, waiting up to the specified wait time if necessary for an element to become available.
检索并移除此队列的头部,如果此队列中没有任何元素,则等待指定等待的时间(如果有必要)。
<nobr style="line-height:21px">abstract void</nobr> <nobr style="line-height:21px"><span style="line-height:21px; margin-right:2px"><a rel="nofollow" href="http://developer.android.com/reference/java/util/concurrent/BlockingQueue.html#put(E)" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">put</a></span>(E e)</nobr>
Inserts the specified element into this queue, waiting if necessary for space to become available.
将指定的元素添加到此队列的尾部,如果必要,将等待可用的空间。
<nobr style="line-height:21px">abstract int</nobr> <nobr style="line-height:21px"><span style="line-height:21px; margin-right:2px"><a rel="nofollow" href="http://developer.android.com/reference/java/util/concurrent/BlockingQueue.html#remainingCapacity()" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">remainingCapacity</a></span>()</nobr>
Returns the number of additional elements that this queue can ideally (in the absence of memory or resource constraints) accept without blocking, or Integer.MAX_VALUEif there is no intrinsic limit.
<nobr style="line-height:21px">abstract boolean</nobr> <nobr style="line-height:21px"><span style="line-height:21px; margin-right:2px"><a rel="nofollow" href="http://developer.android.com/reference/java/util/concurrent/BlockingQueue.html#remove(java.lang.Object)" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">remove</a></span>(<a rel="nofollow" href="http://developer.android.com/reference/java/lang/Object.html" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">Object</a>o)</nobr>
Removes a single instance of the specified element from this queue, if it is present.
<nobr style="line-height:21px">abstract E</nobr> <nobr style="line-height:21px"><span style="line-height:21px; margin-right:2px"><a rel="nofollow" href="http://developer.android.com/reference/java/util/concurrent/BlockingQueue.html#take()" style="color:rgb(0,102,153); line-height:21px; text-decoration:none">take</a></span>()</nobr>
Retrieves and removes the head of this queue, waiting if necessary until an element becomes available.
检索并移除此队列的头部,如果此队列不存在任何元素,则一直等待。
<wbr style="line-height:25px">ArrayBlockingQueue<br style="line-height:25px"></wbr>
ArrayBlockingQueue 是一个基于数组实现的,更多内容请参考《 ArrayBlockingQueue
LinkedBlockingQueue
<wbr style="line-height:25px"><span style="color:#993300; line-height:25px"><wbr style="line-height:25px">LinkedBlockingQueue</wbr></span><span style="color:#003366; line-height:25px">是一个基于链接节点的、范围任意的blockingqueue的实现<wbr style="line-height:25px">。</wbr></span>更多内容请参考《</wbr>
LinkedBlockingQueue
DelayQueue
DelayQueue是实现Delayed接口的元素的一个无界阻塞队列,只有在延迟期满时才能从中提取元素。
关于此的更多内容请参考《
DelayQueue
<wbr style="line-height:25px">PriorityBlockingQueue<br style="line-height:25px"></wbr><wbr style="line-height:25px"></wbr> PriorityBlockingQueue 一个无界的阻塞队列<wbr style="line-height:25px">,它使用与类PriorityQueue相同的顺序规则,并且提供了阻塞检索的操作。<br style="line-height:25px"> 关于此的详细内容请参考《</wbr> PriorityBlockingQueue
SynchronousQueue
SynchronousQueue也好是BlockingQueue的一种实现。它是这样的 一种阻塞队列,其中每个put必须等待一个take,反之亦然。同步队列没有任何内部容量,甚至连一个队列的容量都没有。
关于此的详细内容请参考《 SynchronousQueue
例1<wbr style="line-height:25px">:<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">以下是来自java文档基于典型的生产者-使用者场景的一个用例。<br style="line-height:25px"></wbr></span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">class</span><span style="color:#ff6600; line-height:25px">Producer</span><span style="color:#993300; line-height:25px">implements</span><span style="color:#3366ff; line-height:25px">Runnable{<br style="line-height:25px"> privatefinalBlockingQueuequeue;<br style="line-height:25px"> Producer(BlockingQueueq){queue=q;}<br style="line-height:25px"></span><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#3366ff; line-height:25px">run(){<br style="line-height:25px"> try{<br style="line-height:25px"> while(true){queue.put(produce());}<br style="line-height:25px"> }catch(InterruptedExceptionex){...handle...}<br style="line-height:25px"> }<br style="line-height:25px"> Objectproduce(){...}<br style="line-height:25px"> }<br style="line-height:25px"></span><span style="color:#993300; line-height:25px">class</span><span style="color:#3366ff; line-height:25px">ConsumerimplementsRunnable{<br style="line-height:25px"> privatefinalBlockingQueuequeue;<br style="line-height:25px"> Consumer(BlockingQueueq){queue=q;}<br style="line-height:25px"></span><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#3366ff; line-height:25px">run(){<br style="line-height:25px"></span><span style="color:#993300; line-height:25px">try</span><span style="color:#3366ff; line-height:25px">{<br style="line-height:25px"></span><span style="color:#993300; line-height:25px">while</span><span style="color:#3366ff; line-height:25px">(true){consume(queue.take());}<br style="line-height:25px"> }</span><span style="color:#993300; line-height:25px">catch</span><span style="color:#3366ff; line-height:25px">(InterruptedExceptionex){...handle...}<br style="line-height:25px"> }<br style="line-height:25px"> voidconsume(Objectx){...}<br style="line-height:25px"> }<br style="line-height:25px"></span><span style="color:#993300; line-height:25px">class</span><span style="color:#3366ff; line-height:25px">Setup{<br style="line-height:25px"></span><span style="color:#993300; line-height:25px">void</span><span style="color:#ff6600; line-height:25px">main()</span><span style="color:#3366ff; line-height:25px">{<br style="line-height:25px"> BlockingQueueq=newSomeQueueImplementation();<br style="line-height:25px"> Producerp=newProducer(q);<br style="line-height:25px"> Consumerc1=newConsumer(q);<br style="line-height:25px"> Consumerc2=newConsumer(q);<br style="line-height:25px"> newThread(p).start();<br style="line-height:25px"> newThread(c1).start();<br style="line-height:25px"> newThread(c2).start();<br style="line-height:25px"> }<br style="line-height:25px"> }</span></wbr></wbr>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值