blockingqueue学习总结
来源:互联网 发布:养比特犬体验知乎 编辑:程序博客网 时间:2024/05/29 11:03
定义:
blockingqueue(阻塞队列)支持两种操作,当队列为空时,获取元素的线程会等待队列变为非空,当队列已满时,存储元素的线程会等待队列有空闲可用。阻塞队列通常用于消费者/生产者的场景,生产者就是往队列中添加元素的线程,消费者就是从队列中获取元素的线程,blockingqueue就是生产者存放元素的容器,也是消费者获取元素的容器。
七个实现类:
ArrayBlockingQueue:
一个由数组结构组成的有界阻塞队列。
此队列按照先进先出(FIFO)的原则对元素进行排序,默认情况下不保证访问者公平的访问队列,即当队列可用时,按照阻塞的先后顺序访问队列,先阻塞的生产者线程,可以先往队列里插入元素,先阻塞的消费者线程,可以先从队列中获取元素,通常情况下为了保证公平性会降低吞吐量。
DelayQueue:
一个使用优先级队列(PriorityQueue)实现的无界阻塞队列。
支持延时获取,队列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素。只有在延时期满时才能从队列中提取元素。
应用场景:
队列中的Delayed必须实现compareTo来指定元素的顺序。缓存系统的设计:可以用DelayQueue保存缓存元素的有效期,使用一个线程循环查询DelayQueue,一旦能从队列中获取元素时候,表示缓存有效期到了。
定时任务调度:使用DelayQueue保存当天将会执行的任务和执行时间。一旦从队列中获取到任务就开始执行,比如TimerQueue就是用DelayQueue实现的。
LinkedBlockingDeque:
一个由链表结构组成的双向阻塞队列。
可以从队列的两端插入和获取元素,双端队列因为多了一个操作队列的入口,在多线程同时入队时,减少了一半的竞争。相比其他的阻塞队列,LinkedBlockingDeque多了addFirst,addLast,offerFirst,offerLast,peekFirst,peekLast等方法,以First结尾的方法表示插入/获取(peek)/移除双端队列的第一个元素。以Last结尾的方法,表示插入/获取(peek)/移除双端队列的最后一个元素。add方法等同于addLast方法,remove方法等同于removeFirst方法。
在初始化时可以设置容量防止其过渡膨胀。
LinkedBlockingQueue:
一个由链表结构组成的有界阻塞队列。
此队列按照先进先出(FIFO)的原则对元素进行排序,默认和最大长度为Integer.MAX_VALUE。
LinkedTransferQueue:
一个由链表结构组成的无界阻塞队列
相对于其他阻塞队列,LinkedTransferQueue多了tryTransfer和transfer方法。
transfer方法。如果当前又消费者正在等待接受元素(消费者使用take()或poll(timeout)时),transfer方法可以把生产者传入的元素立刻transfer给消费者。如果没有消费者在等待接收元素,transfer方法会将元素存放在队列的tail节点,并等到该元素被消费了才返回。
tryTransfer方法。则是用来试探下生产者传入的元素是否能直接传给消费者。如果没有消费者等待接收元素,则返回false。和transfer方法的区别是,tryTransfer方法无论消费者是否接收,方法立即返回,而transfer方法是必须等到消费者消费了才返回。
tryTransfer(E e, Long timeout, TimeUnit unit)方法,则是试图把生产者传入的元素直接传给消费者,如果没有消费者消费该元素,则等待指定时间后返回,被消费,返回true,没被消费,返回false。
PriorityBlockingQueue:
一个支持优先级排序的无界阻塞队列。
默认情况下元素采取自然顺序排序,也可以通过比较器comparator来指定元素的排序规则,元素按照升序排序。
SynchronousQueue:
一个不存储元素的阻塞队列。
每一个put操作必须等待一个take操作,否则不能继续添加元素,适用于传递性场景,比如在一个线程中使用的数据,传递给另一个线程,SyncchronousQueue吞吐量高于LinkedBlockingQueue和ArrayBlockingQueue。
四种等待形式:
1.抛异常(Throws Exception):IllegalStateException("Queue full")/NoSuchElementException
2.返回一个特殊值(Special value):null/false
3.无限期的锁住当前线程,等待,直到塞入/取出成功(Blocks)
4.超时退出(Times out):设定等待时间
参考如下表格
Throws ExceptionSpecial valueBlocksTimes outInsertadd(e)offer(e)put(e)offer(e, time, unit)Removeremove()poll()take()poll(time, unit)Examineelement()peek()not applicablenot applicable方法概述:
addboolean add(E e)当队列没满时,插入队列成功,返回true,当队列已满,插入队列失败,抛出IllegalStateException异常。
当使用有界队列时,更倾向于使用offer。
Parameters:
e-插入队列对象
Returns:
true
Throws:
IllegalStateException-当要插入的队列已满时offerboolean offer(E e)
ClassCastException-插入队列的对象类型与队列泛型转换异常
NullPointerException-插入队列的对象为空
IllegalArgumentException-插入非法对象
当队列没满时,插入队列成功,返回true,当队列已满,返回false。
当使用有界队列时,如果希望队列已满时抛出异常,更倾向于使用add。
Parameters:
e-插入队列对象
Returns:
true/false
Throws:
ClassCastException-插入队列的对象类型与队列泛型转换异常putvoid put(E e) throws InterruptedException
NullPointerException-插入队列的对象为空
IllegalArgumentException-插入非法对象
当队列已满时,等待,直到队列有空闲。
Parameters:
e-插入队列对象
Throws:
InterruptedException-阻塞过程中发生异常offerboolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException
ClassCastException-插入队列的对象类型与队列泛型转换异常
NullPointerException-插入队列的对象为空
IllegalArgumentException-插入非法对象
当队列已满时,在指定时间内等待,直到队列有空闲。
Parameters:
e-插入队列对象
timeout-超时时间
unit-时间单位
Returns:
true/false
Throws:
InterruptedException-阻塞过程中发生异常takeE take() throws InterruptedException
ClassCastException-插入队列的对象类型与队列泛型转换异常
NullPointerException-插入队列的对象为空
IllegalArgumentException-插入非法对象
获取并移除队列头部的对象,等待,直到队列中有对象可用。
Returns:
队列顶部的对象
Throws:
InterruptedException-阻塞过程中发生异常pollE poll(long timeout, TimeUnit unit) throws InterruptedException
获取并移除队列头部的对象,在指定时间内等待,直到队列中有对象可用。
Parameter:
timeout-超时时间
unit-时间单位
Returns:
队列顶部的对象/null(超时)
Throws:
InterruptedException-阻塞过程中发生异常remainingCapacityint remainingCapacity()
返回在队列不阻塞的情况下,剩余可添加对象数,如果是无界队列,或者没有设置队列限制,则返回Integer.MAX_VALUE
注意,我们无法根据队列现有的剩余容量情况,确保一个线程能插入成功,因为其他线程也有可能插入或移除对象。
Returns:
剩余容量removeboolean remove(Object o)
移除队列中的单个实例,如果该实例存在。通常的,如果队列中存在一个或多个入参中的元素,移除队列中与这个元素相等的元素。如果队列中存在这个元素,则返回true。
Parameter:
o-需要被从队列中移除的对象
Throws:
ClassCastException-插入队列的对象类型与队列泛型转换异常containsboolean contains(Object o)
NullPointerException-插入队列的对象为空
如果参数中元素存在于队列中,则返回true。通常的,如果队列中存在一个或多个入参中的元素,则返回true。
Parameter:
o-需要校验是否存在于队列中的对象
Throws:
ClassCastException-插入队列的对象类型与队列泛型转换异常drainToint drainTo(Collecntion<? super E> c)
NullPointerException-插入队列的对象为空
从队列中移除所有元素,添加到入参指定的集合中,此操作要比多次从队列中poll操作更高效。当试图向入参指定的集合中添加元素时,会发生失败情况。当关联异常被抛出,表示两个集合和队列可能两者都不会添加,可能添加到其中一个,也可能两者都被添加入该元素。
Parameter:
c-元素要传输的集合
Return:
传输成功的元素个数
Throws:
UnsupportedOperationException-集合不支持添加的元素drainToboolean drainTo(Collection<? extends E> c, int maxElements)
ClassCastException-插入队列的对象类型与队列泛型转换异常
NullPointerException-插入队列的对象为空
IllegalArgumentException-插入非法对象
从队列中移除所有元素,添加到入参指定的集合中,此操作要比多次从队列中poll操作更高效。当试图向入参指定的集合中添加元素时,会发生失败情况。当关联异常被抛出,表示两个集合和队列可能两者都不会添加,可能添加到其中一个,也可能两者都被添加入该元素。如果企图将队列转换入自己本身,将抛IllegalArgumentException异常。更进一步的,如果指定集合在操作过程中被改动了,未定义该操作的行为。
Parameters:
c-元素要转换添加的集合
maxElements-传输元素的最大个数
Returns:
被传输的元素个数
Throws:
UnsupportedOperationException-集合不支持添加的元素
ClassCastException-插入队列的对象类型与队列泛型转换异常
NullPointerException-插入队列的对象为空
IllegalArgumentException-插入非法对象
参考资料:
1.https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
2.http://www.infoq.com/cn/articles/java-blocking-queue
demo文档
- blockingqueue学习总结
- BlockingQueue总结
- BlockingQueue学习
- BlockingQueue和DelayQueue学习
- 学习阻塞队列BlockingQueue
- 3.集合--BlockingQueue总结1
- BlockingQueue
- BlockingQueue
- BlockingQueue
- BlockingQueue
- BlockingQueue
- BlockingQueue
- BlockingQueue
- BlockingQueue
- BlockingQueue
- BlockingQueue
- BlockingQueue
- BlockingQueue
- 两整数相加减
- JDOM 2 测试代码
- monkeyrunner 的初次使用时该怎么配置
- ShaderForge-角色发光效果
- PHP常用数组(Array)函数
- blockingqueue学习总结
- Android WebView全面讲解
- Device Tree(三):代码分析
- 悬浮按钮+切换布局
- Angular4
- for循环的执行顺序(案例+详解)
- C++协程库coroutine使用指南
- 机器学习笔记之(三)常用的求导公式
- hdu 1233 还是畅通工程 最小生成树