框架概览


接口介绍

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,俗称传输队列,支持生产者等待消费者获取元素。


Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐