本文部分摘自《Java 并发编程的艺术》
阻塞队列概述
阻塞队列(BlockingQueue)是一个支持两个附加操作的队列,这两个附加的操作支持阻塞的插入和移除方法:
- 支持阻塞的插入方法:意思是当队列为满时,队列会阻塞插入元素的线程,直到队列不为满
- 支持阻塞的移除方法:意思是当队列为空时,获取元素的线程会等待队列变为非空
阻塞队列通常用在生产者和消费者的场景,生产者是向队列添加元素的线程,消费者是从队列获取元素的线程。阻塞队列就是生产者用来存放元素,消费者用来获取元素的容器
在阻塞队列不可用时,这两个附加操作提供了四种处理方式:
抛出异常 | 返回特殊值 | 一直阻塞 | 超时退出 | |
---|---|---|---|---|
插入方法 | add(o) | offer(o) | put(o) | offer(o, timeout, timeunit) |
移除方法 | remove(o) | poll() | take(o) | poll(o, timeout, timeunit) |
检查方法 | element() | peek() | — | — |
抛出异常
当队列满时,如果再往队列里插入元素,会抛出 IllegalStateException 异常。当队列空时,从队列里获取元素会抛出 NoSuchElementException 异常
返回特殊值
当往队列插入元素,会返回元素是否插入成功,成功返回 true,否则返回 false。如果是移除方法,则是从队列里取出一个元素,如果没有则返回 null
一直阻塞
当阻塞队列满时,如果生产者线程往队列里 put 元素,队列会一直阻塞生产者线程,直到队列可用或者响应中断。当队列为空时,如果消费者线程从队列里 take 元素,队列会阻塞消费者线程,直到队列不为空
超时退出
当阻塞队列满时,如果生产者线程往队列里插入元素,队列会阻塞生产者线程一段时间,如果超过了指定的时间,生产者线程就会退出
Java 里的阻塞队列
JDK7 提供了 7 个阻塞队列,如下:
1. ArrayBlockingQueue
ArrayBlockingQueue 是一个用数组实现的有界阻塞队列,此队列按照先进先出(FIFO)的原则对元素进行排序,默认情况下不保证线程公平的访问队列
2. LinkedBlockingQueue
LinkedBlockingQueue 是一个用链表实现的有界阻塞队列,此队列的默认和最大长度为 Integer.MAX_VALUE,此队列按照先进先出的原则对元素进行排序
3. PriorityBlockingQueue
PriorityBlockingQueue 是一个支持优先级的无界阻塞队列,默认情况下元素采取自然顺序升序排序,也可以定义类实现 compareTo() 方法来指定元素排序规则,或者初始化队列时,指定构造参数 Comparator
4. DelayQueue
DelayQueue 是一个支持延时获取元素的无界阻塞队列,队列使用 PriorityQueue 来实现,队列中的元素必须实现 Delay 接口,在创建元素时可以指定多久才能从队列中获取当前元素,只有延迟期满才能从队列中提取元素
DelayQueue 可以运用在以下应用场景:
- 缓存系统的设计:可以用 DelayQueue 保证缓存元素的有效期,使用一个线程循环查询 DelayQueue,一旦能从中获取元素,表示缓存有效期到了
- 定时任务调度:使用 DelayQueue 保存当天将会执行的任务和执行时间,一旦从 DelayQueue 中获取到任务就开始执行
5. SynchronousQueue
SynchronousQueue 是一个不存储元素的阻塞队列,每一个 put 操作必须等待一个 take 操作,否则不能继续添加元素
6. LinkedTransferQueue
LinkedTransferQueue 是一个由链表结构组成的无界阻塞队列 TransferQueue 队列,相对于其他阻塞队列,LinkedTransferQueue 多了 tryTransfer 和 transfer 方法
transfer 方法
如果当前有消费者正在等待接收元素(消费者使用 take 方法或带时间限制的 poll 方法时),transfer 方法可以把生产者传入的元素立刻 transfer(传输)给消费者。如果没有消费者在等待接收元素,transfer 方法会将元素存放在队列的 tail 节点,并等到该元素被消费者消费了才返回
tryTransfer 方法
tryTransfer 方法是用来试探生产者传入的元素是否能直接传给消费者,如果没有消费者等待接收元素,则返回 false,和 transfer 方法的区别是 tryTransfer 方法无论消费者是否接收,方法立即返回,也可以带上时间限制
7. LinkedBlockingDeque
LinkedBlockingDeque 是一个由链表结构组成的双向阻塞队列,因为多了一个操作队列的入口,在多线程同时入队时,也就少了一半的竞争
原文转载:http://www.shaoqun.com/a/645726.html
1淘网:https://www.ikjzd.com/w/1698
浩方:https://www.ikjzd.com/w/1046
本文部分摘自《Java并发编程的艺术》阻塞队列概述阻塞队列(BlockingQueue)是一个支持两个附加操作的队列,这两个附加的操作支持阻塞的插入和移除方法:支持阻塞的插入方法:意思是当队列为满时,队列会阻塞插入元素的线程,直到队列不为满支持阻塞的移除方法:意思是当队列为空时,获取元素的线程会等待队列变为非空阻塞队列通常用在生产者和消费者的场景,生产者是向队列添加元素的线程,消费者是从队列获取元
优1宝贝:https://www.ikjzd.com/w/1507
电霸:https://www.ikjzd.com/w/2597
首信易支付:https://www.ikjzd.com/w/1841
Wayfair平台有哪些与众不同的地方?:https://www.ikjzd.com/home/104487
那些年我踩过Deal 站外的坑,希望能够帮你!:https://www.ikjzd.com/home/137248
四国准备统一货币,对跨境贸易有哪些好处?:https://www.ikjzd.com/home/102923
No comments:
Post a Comment