一、ArrayBlockingQueue
基于 ReentrantLock 的有界阻塞队列,支持公平锁
ArrayBlockingQueue
维护了一把全局锁,无论是出队还是入队,都共用这把锁,这就导致任一时间点只有一个线程能够执行。那么对于 “生产者-消费者” 模式来说,意味着生产者和消费者不能并发执行,可能出现性能瓶颈
二、DelayQueue
DelayQueue
是一个无界阻塞队列,用于放置实现了Delayed
接口的对象,其中的对象只能在其到期时才能从队列中取走。这种队列是有序的,即队头对象的延迟到期时间最长。不能将 null 元素放到 DelayQueue 中
三、LinkedBlockingDeque
和
LinkedBlockingQueue
类似,提供了队列两端操作的方法
四、LinkedBlockingQueue
近似有界阻塞队列,容量大小默认为
Integer.MAX_VALUE
LinkedBlockingQueue
维护了两把锁:takeLock
和 putLock
。takeLock
用于控制出队的并发,putLock
用于入队的并发。这也就意味着,同一时刻,只能只有一个线程能执行入队/出队操作,其余入队/出队线程会被阻塞;但是,入队和出队之间可以并发执行,即同一时刻,可以同时有一个线程进行入队,另一个线程进行出队,这中设计可以提高吞吐量
五、LinkedTransferQueue
六、PriorityBlockingQueue
无解阻塞队列,容量大小默认为
Integer.MAX_VALUE
,底层是基于数组实现的堆结构
PriorityBlockingQueue 的特点:
PriorityBlockingQueue
与之前介绍的阻塞队列最大的不同之处在于它是一种 优先级队列,也就是说元素并不是以 FIFO 的方式出/入队,而是以按照权重大小的顺序出队PriorityBlockingQueue
是真正的无界队列(仅受内存大小限制),它不像ArrayBlockingQueue
那样构造时必须指定最大容量,也不像LinkedBlockingQueue
默认容量为Integer.MAX_VALUE
- 由于
PriorityBlockingQueue
是按照元素的权重进入排序,所以队列中的元素必须是可以比较的,也就是说元素必须实现Comparable
接口 - 由于 PriorityBlockingQueue 无界队列,所以插入元素永远不会阻塞线程
七、SynchronousQueue
SynchronousQueue
是一个没有数据缓冲的阻塞队列,生产者线程对其的插入操作 put 必须等待消费者的移除操作 take,反过来也一样
八、ConcurrentLinkedDeque
基于 CAS 的无锁、无界、非阻塞队列,适用于多消费者模式。和
ConcurrentLinkedQueue
类似,提供了队列两端操作的方法
九、ConcurrentLinkedQueue
基于 CAS 的无锁、无界、非阻塞队列,适用于多消费者模式
总结
队列 | 阻塞 | 有界 | 线程安全实现原理 | 数据结构 | 使用场景 | 特点 |
---|---|---|---|---|---|---|
ArrayBlockingQueue | 阻塞 | 有界 | 基于 ReentrantLock ,队列出入队操作只维护一把锁 | 数组 | 生产者-消费者模式 | 1 对于高并发场景,由于生产者-消费者共用一把锁,可能出现性能瓶颈 2 控制对象的内部锁是否采用公平锁,默认采用非公平锁 |
LinkedBlockingDeque | 阻塞 | 有界 | 基于 ReentrantLock | 双向链表 | 单/多生产者-单消费者模式 | 2 默认链表长度为 Integer.MAX_VALUE ,如果生产速度大于消费速度,会将系统内存耗尽 |
LinkedBlockingQueue | 阻塞 | 有界 | 基于 ReentrantLock,LinkedBlockingQueue 维护了两把锁:takeLock 和 putLock 。takeLock 用于控制出队的并发,putLock 用于入队的并发 | 链表 | 单/多生产者-单消费者模式 | 1 可以同时进行出队和入队操作,有效提升吞吐量 2 默认链表长度为 Integer.MAX_VALUE ,如果生产速度大于消费速度,会将系统内存耗尽 |
LinkedTransferQueue | 阻塞 | 有界 | ||||
ConcurrentLinkedDeque | 非阻塞 | 无界 | 基于 CAS、基于 VarHandler(JDK 9 +) | 单/多生产者-多消费者模式 | ||
ConcurrentLinkedQueue | 非阻塞 | 无界 | 基于 CAS、基于 VarHandler(JDK 9 +) | 单/多生产者-多消费者模式 | ||
DelayQueue | ||||||
PriorityBlockingQueue | 基于数组实现的堆 | 2 默认链表长度为 Integer.MAX_VALUE ,如果生产速度大于消费速度,会将系统内存耗尽 | ||||
SynchronousQueue |