1.BlockingQueue定义的常用方法如下
抛出异常 | 特殊值 | 阻塞 | 超时 | |
插入 | add(e) | offer(e) | put(e) | offer(e,time,unit) |
移除 | remove() | poll() | take() | poll(time,unit) |
检查 | element() | peek() | 不可用 | 不可用 |
1)add(anObject):把anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回异常
2)offer(anObject):表示如果可能的话,将anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false.
3)put(anObject):把anObject加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里面有空间再继续.
4)poll(time):取走BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null
5)take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到Blocking有新的对象被加入为止
2、BlockingQueue的几个注意点
【1】BlockingQueue 可以是限定容量的。它在任意给定时间都可以有一个remainingCapacity,超出此容量,便无法无阻塞地put 附加元素。没有任何内部容量约束的BlockingQueue 总是报告Integer.MAX_VALUE 的剩余容量。
【2】BlockingQueue 实现主要用于生产者-使用者队列,但它另外还支持Collection
接口。因此,举例来说,使用remove(x) 从队列中移除任意一个元素是有可能的。然而,这种操作通常不 会有效执行,只能有计划地偶尔使用,比如在取消排队信息时。
【3】BlockingQueue 实现是线程安全的。所有排队方法都可以使用内部锁或其他形式的并发控制来自动达到它们的目的。然而,大量的 Collection 操作(addAll、containsAll、retainAll 和removeAll)没有 必要自动执行,除非在实现中特别说明。因此,举例来说,在只添加了c 中的一些元素后,addAll(c) 有可能失败(抛出一个异常)。
3、简要概述BlockingQueue常用的实现类
ArrayBlockingQueue
实现细节
1.基于数组实现循环队列: 也就意味着预分配了空间,不过基于数组在性能上比基于链表的实现性能高些(CPU cache更友好吧)
2.在读写队列的时候都是用一个ReentrantLock对整个队列上锁(默认非公平锁,公平锁会线程饥饿)。
3.一旦创建,大小固定,有界队列。比较适合作为有界缓冲。大小固定,也就不必纠结空间回收的问题了,这个是优点也是缺点,看怎么理解了。
4.实现中使用了Condition来控制notFull和notEmpty条件: 例如take取数据的时候由于队列空了被阻塞;有新的数据put了,就可以signal那些take数据被阻塞的线程了。不利用Condition的话自己利用Object的notify、wait方法也可以做,不过显然麻烦多了。
应用场景
比较适合作为有界缓冲。
LinkedBlockingQueue
实现细节
1.基于链表实现: 大小可变,更加灵活。默认最大大小为Integer.MAX_VALUE。
2.在队首(putLock)和队尾使用两把锁: 可以实现读写并发,吞吐性能比ArrayBlockingQueue好很多,
也利用Condition来做非空非满的条件判断
应用场景
常见的不涉及大量互斥资源的生产消费的情况,都可以用该类实现生产消费模型
SynchronousQueue
总结下有以下特点:
1.容量永远为0
2.适合一对一的生产消费场景,由于经过很多优化,性能是很好的。因此容量为1的队列,就别使用其他阻塞queue了
3.实现上也用了CAS、自旋锁
应用场景
性能比前面几种Queue都要高
适合当做一个生产者和消费者之间的汇合点,传递数据。
DelayedQueue
原理
1.延迟队列内部使用优先队列管理任务
2.使用一个availabe Condition条件来做唤醒
3.使用的heap数据结构(因为用的优先队列是基于堆得)
应用场景
延迟任务、定期任务、周期任务
PriorityBlockingQueue
原理
1.存储的对象必须是实现Comparable接口
2.基于heap的数据机构(array-based binary heap)
应用场景
有优先级的任务
LinkedTransferQueue
原理
1.非阻塞
2.基于CAS无锁
3.Doug Lea说从功能角度来讲,LinkedTransferQueue实际上是ConcurrentLinkedQueue、SynchronousQueue(公平模式)和LinkedBlockingQueue的超集。而且LinkedTransferQueue更好用,因为它不仅仅综合了这几个类的功能,同时也提供了更高效的实现。