框架概览
接口介绍
Queue
俗称队列,其设计目标是存储处理前的元素。在Collection基础上,新增了入队、出队、访问队首元素的方法:
1)Queue有两套功能相同的方法:add、remove、element分别为入队、出队、访问队首元素方法的抛出异常版本;offer、poll、peek则为返回特殊值的版本:
2)offer在有界队列中常用,当队列已满时,元素入队会返回false而不是抛出异常,因为这一般当作正常情况;
3)按照元素出入队顺序可分为:FIFO队列、LIFO队列、优先级队列,这三种队列的一个共同点是:remove、poll返回的元素都是队首元素:
4)Queue一般不自行实现基于元素的equals、hashCode方法,因为在队列中可能存在多个相等的元素,但是它们的顺序是不同的,“顺序”在队列中是很特别的。
BlockingQueue
俗称阻塞队列,支持删除时一直等到有元素,增加时一直等到队列有容量空间:
1)其设计主要目标是用作生产者—消费者队列;
2)BlockingQueue实现类是线程安全的,其方法采用锁或其他形式并发(如lock-free、wait-free等)实现原子性,对于批量操作addAll、ContainsAll、retainAll、removeAll不一定是原子的,除非特别实现;
3)其存在4种不同版本的操作:
4)BlockingQueue有内部容量限制,可采用remainingCapacity()查看,若无则为Integer.MAX_VALUE;
5)不支持null元素,增加null会抛出NullPointerException,null用于给poll操作检查是否失败;
6)内存一致性原则:先于“添加元素到BlockingQeque队列”的操作happens-before后于“获取或删除该元素”的操作;
7)生产者—消费者应用场景,在多个生产者、消费者线程下线程安全:
class Producer implements Runnable { private final BlockingQueue queue; Producer(BlockingQueue q) { queue = q; } public void run() { try { while (true) { queue.put(produce()); } } catch (InterruptedException ex) { ... handle ...} } Object produce() { ... } } class Consumer implements Runnable { private final BlockingQueue queue; Consumer(BlockingQueue q) { queue = q; } public void run() { try { while (true) { consume(queue.take()); } } catch (InterruptedException ex) { ... handle ...} } void consume(Object x) { ... } } class Setup { void main() { BlockingQueue q = new SomeQueueImplementation(); Producer p = new Producer(q); Consumer c1 = new Consumer(q); Consumer c2 = new Consumer(q); new Thread(p).start(); new Thread(c1).start(); new Thread(c2).start(); } }
Deque
俗称双端队列,支持有界容量、无界容量。
Deque不支持List的索引访问方式;尽管允许null元素,但尽量避免使用,null用做方法的特殊值;一般不定义基于元素的equals、hashCode方法,而采用Object的原生方法。
自有方法:
用作FIFO等效方法:
用作LIFO(Stack)等效方法:
BlockingDeque
Blocking+Deque:
内存一致性原则:先于“添加元素到BlockingDeque队列”的操作happens-before后于“获取或删除该元素”的操作;
TransferQueue
Blocking+Transfer,俗称传输队列,支持生产者等待消费者获取元素。