BlockingQueue阻塞队列
Blocking Queue是一个带阻塞功能的队列,当入队列时,若队列已满,则阻塞调 用者;当出队列时,若队列为空,则阻塞调用者。
在Concurrent包中,BlockingQueue是一个接口,有许多个不同的实现类
❑ 普通阻塞队列:基于数组的ArrayBlockingQueue,基于链表的LinkedBlockingQueue
❑ 优先级阻塞队列:PriorityBlockingQueue。
❑ 延时阻塞队列:DelayQueue。
❑ 其他阻塞队列:SynchronousQueue和LinkedTransferQueue。
主要方法有:
1 2 3 4 5 6 7 8 | //入队,如果队列满,等待直到队列有空间 void put(E e) throws InterruptedException; //出队,如果队列空,等待直到队列不为空,返回头部元素 E take() throws InterruptedException; //入队,如果队列满,最多等待指定的时间,如果超时还是满,返回false boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException; //出队,如果队列空,最多等待指定的时间,如果超时还是空,返回null E poll( long timeout, TimeUnit unit) throws InterruptedException; |
普通阻塞队列
ArrayBlockingQueue是基于循环数组实现的,有界,创建时需要指定大小,且在运行过程中不会改变
LinkedBlockingQueue是基于单向链表实现的,在创建时可以指定最大长度,也可以不指定,默认是无限的,节点都是动态创建的
优先级阻塞队列
普通阻塞队列是先进先出的,而优先级队列是按优先级出队的,优先级高的先出
PriorityBlockingQueue没有大小限制,是无界的,内部的数组大小会动态扩展,要求元素要么实现Comparable接口,要么创建PriorityBlockingQueue时提供一个Comparator对象。
延时阻塞队列
延时阻塞队列DelayQueue是一种特殊的优先级队列,它是无界的。
它要求每个元素都实现Delayed接口,该接口的声明为:
1 2 3 | public interface Delayed extends Comparable<Delayed> { long getDelay(TimeUnit unit); } |
Delayed扩展了Comparable接口,也就是说,DelayQueue的每个元素都是可比较的,它有一个额外方法getDelay返回一个给定时间单位unit的整数,表示再延迟多长时间,如果小于等于0,则表示不再延迟。
DelayQueue可以用于实现定时任务,它按元素的延时时间出队。它的特殊之处在于,只有当元素的延时过期之后才能被从队列中拿走,也就是说,take方法总是返回第一个过期的元素,如果没有,则阻塞等待。
其他阻塞队列
SynchronousQueue与一般的队列不同,它不算一种真正的队列,没有存储元素的空间,连存储一个元素的空间都没有。它的入队操作要等待另一个线程的出队操作,反之亦然。如果没有其他线程在等待从队列中接收元素,put操作就会等待。take操作需要等待其他线程往队列中放元素,如果没有,也会等待。SynchronousQueue适用于两个线程之间直接传递信息、事件或任务。
LinkedTransferQueue实现了TransferQueue接口,TransferQueue是BlockingQueue的子接口,但增加了一些额外功能,生产者在往队列中放元素时,可以等待消费者接收后再返回,适用于一些消息传递类型的应用中。
BlockingDeque
BlockingDeque定义了一个阻塞的双端队列接口,如下所示。
可以看到,该接口在继承了BlockingQueue接口的同时,增加了对应的双端队列操作接口。该接口只有一个实现,就是LinkedBlockingDeque。
和LinkedBlockingQueue基本一样,只是Linked BlockingQueue是单向链表,而LinkedBlockingDeque是双向链表。
所谓双向队列指的是可以从队列的两端插入和移出元素。双向队列因为多了一个操作队列的入口,在多线程同时入队时,也就减少了一半的竞争。相比其他的阻塞队列,LinkedBlockingDeque多了addFirst、addLast、offerFirst、offerLast、peekFirst和peekLast等方法,以First单词结尾的方法,表示插入、获取(peek)或移除双端队列的第一个元素。以Last单词结尾的方法,表示插入、获取或移除双端队列的最后一个元素。另外,插入方法add等同于addLast,移除方法remove等效于removeFirst。但是take方法却等同于takeFirst,使用时还是用带有First和Last后缀的方法更清楚。
参考: Java编程的逻辑 17.4 并发队列
Java并发编程的艺术 6.3.2 Java里的阻塞队列
Java并发实现原理:JDK源码剖析 5.1 BlockingQueue
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2019-01-27 ajax 跨域 springboot
2018-01-27 js,jquery 获取滚动条高度和位置, 元素距顶部距离
2018-01-27 java 向上转型与向下转型
2018-01-27 Java 判断相等