Queue 体系
Queue 是一种先进先出的队列。
ArrayBlockingQueue 和 LinkedBlockingQueue 是带阻塞特性,基于锁来实现。ArrayBlockingQueue 采用同一把锁来控制出、入队列操作;LinkedBlockingQueue 用两把锁来分别控制出、入队列操作,提高了并发性能。
ConcurrentLinkedQueue 非阻塞,采用无锁算法、利用 CAS 操作来实现。
0.1 BlockingQueue
当生产者向队列添加元素但队列已满时,生产者会被阻塞;当消费者从队列移除元素、但队列为空时,消费者会被阻塞。
其实现类必须是线程安全,入队列 happen-before 出队列。
0.2 TransferQueue
继承自 BlockingQueue,更进一步:生产者会一直阻塞直到添加到队列的元素被某一个消费者所消费(不仅仅是添加到队列)。
特别适用于这种应用间传递消息的场景:生产者有时需要等待消费者接收消息,有时只需把消息放进队列、不需要等待消费者接收。
// 传递元素给消费者,如果需要则等待。确保一次传递完成。
void transfer(E e);
// 非阻塞
boolean tryTransfer(E e);
// 基于等待时间的。
boolean tryTransfer(E e, long timeout, TimeUnit unit);
// 返回是否有在等待接收元素的消费者
// (BlockingQueue.take()或带等待时间的 poll 方法调用)
boolean hasWaitingConsumer();
// 返回大概的在等待接收元素的消费者
//(BlockingQueue.take()或带等待时间的 poll 方法调用)
int getWaitingConsumerCount();
0.3 Deque
允许在两端进行插入、删除元素的线性集合。
实现类:
- ArrayDeque:基于数组加头尾两个指针来实现、非线程安全的。
- LinkedList:基于双向链表实现、非线程安全的。
- ConcurrentLinkedDeque:基于双向链表、CAS 元语实现、无界的。
0.4 BlockingDeque
当 Deque 里没有元素时阻塞消费者,当没有空闲空间时阻塞生产者。
目前只有一个实现类 LinkedBlockingDeque,使用双向链表来存储元素,支持容量限制,用一把锁来保证线程安全性。因为允许在两端进行操作,双向链表更合适。