两点疑问没有解决:
1、为什么ArrayBlockingQueue不使用takeLock、putLock的双锁机制?使用这种锁分离的策略明显效率更高。
2、为什么判断是否存在剩余空间,使用while 而不是if?难道作者怕出现意外,但是什么时候会出现意外呢?
ArrayBlockingQueue
一个数组组成的有界阻塞队列,保持队列基本特性先进先出。
此类对等待的生产者线程和使用者线程进行排序的公平策略选项提供支持。默认情况下,不保证是这种排序策略。通过将fairness设置为true构造的队列允许按照FIFO顺序访问线程。公平性通常会降低吞吐量,但也减少了可变性和避免了“不平衡性”。公平性的保证是通过ReentrantLock的公平锁实现。阻塞超时通过Condition的awaitNanos实现。
属性
1 |
|
put操作
1 |
|
take操作
1 |
|
drainTo操作
1 |
|
LinkedBlockingQueue
一个基于已链接节点的、范围任意的 blocking queue。此队列按 FIFO(先进先出)排序元素。链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。链表动态分配空间可以处理更多的节点,但是动态分配空间会两份一些时间。
可选的容量范围构造方法参数作为防止队列过度扩展的一种方法。如果未指定容量,则它等于 Integer.MAX_VALUE。除非插入节点会使队列超出容量,否则每次插入后会动态地创建链接节点。
与ArrayBlockingQueue的不同点1)一个使用数组,固定大小,一个使用链表,非固定大小,最大是int最大值2)LinkedBlockingQueue使用锁分离策略,正类包含takeLock和putLock两把锁,提高了并发效率。
属性
1 |
|
构造函数
1 |
|
我们可以看出初始化的时候LBQ含有一个Node节点,头指针和尾指针都指向它,count=0。也就是说LBQ一直包含一个多余的Node节点。
put操作
1 |
|
总结
需要公平机制来避免消费者、生产者饥饿,这时使用ABQ再好不过了。
如果队列的大小是有界的话,首选还是ABQ,ABQ的性能更好,不需要申请空间。否则还是LBQ吧!LBQ可以接受突入起来的大量生产者。
- 阻塞队列的效率某些场景的效率会低于非阻塞,下一次再写关于非阻塞队列CourrentLinkedQueue