文章插图
- 在之前的线程池的介绍中我们看到了很多阻塞队列,这篇文章我们主要来说说阻塞队列的事 。
- 阻塞队列也就是
BlockingQueue
,这个类是一个接 - 口,同时继承了
Queue
接口,这两个接口都是在JDK5
中加入的。 BlockingQueue
阻塞队列是线程安全的,在我们业务中是会经常频繁使用到的,如典型的生产者消费的场景,生产者只需要向队列中添加,而消费者负责从队列中获取 。
文章插图
- 如上图展示,我们生产者线程不断的
put
元素到队列,而消费者从中take
出元素处理,这样实现了任务与执行任务类之间的解耦,任务都被放入到了阻塞队列中,这样生产者和消费者之间就不会直接相互访问实现了隔离提高了安全性 。
文章插图
- 上面是
JAVA
中队列Queue
类的类图,我们可以看到它分为两大类,阻塞队列与非阻塞队列 - 阻塞队列的实现接口是
BlockingQueue
而非阻塞队列的接口是ConcurrentLinkedQueue
, 本文主要介绍阻塞队列,非阻塞队列不再过多阐述 BlockingQueue
主要有下面六个实现类,分别是ArrayBlockingQueue
、LinkedBlockingQueue
、SynchronousQueue
、DelayQueue
、PriorityBlockingQueue
、LinkedTransferQueue
。这些阻塞队列有着各自的特点和适用场景,后面详细介绍 。- 非阻塞队列的典型例子如
ConcurrentLinkedQueue
, 它不会阻塞线程,而是利用了CAS
来保证线程的安全 。 - 其实还有一个队列和
Queue
关系很紧密,那就是Deque
,这其实是double-ended-queue
的缩写,意思是双端队列 。它的特点是从头部和尾部都能添加和删除元素,而我们常见的普通队列Queue
则是只能一端进一端出,即FIFO
。
- 阻塞队列的特点就在于阻塞,它可以阻塞线程,让生产者消费者得以平衡,阻塞队列中有两个关键方法
Put
和Take
方法
take
方法的功能是获取并移除队列的头结点,通常在队列里有数据的时候是可以正常移除的 。可是一旦执行take
方法的时候,队列里无数据,则阻塞,直到队列里有数据 。一旦队列里有数据了,就会立刻解除阻塞状态,并且取到数据 。过程如图所示:
文章插图
put方法
put
方法插入元素时,如果队列没有满,那就和普通的插入一样是正常的插入,但是如果队列已满,那么就无法继续插入,则阻塞,直到队列里有了空闲空间 。如果后续队列有了空闲空间,比如消费者消费了一个元素,那么此时队列就会解除阻塞状态,并把需要添加的数据添加到队列中 。过程如图所示:
文章插图
是否有界(容量有多大)
- 此外,阻塞队列还有一个非常重要的属性,那就是容量的大小,分为有界和无界两种 。
- 无界队列意味着里面可以容纳非常多的元素,例如
LinkedBlockingQueue
的上限是Integer.MAX_VALUE
,约为 2 的 31 次方,是非常大的一个数,可以近似认为是无限容量,因为我们几乎无法把这个容量装满 。 - 但是有的阻塞队列是有界的,例如
ArrayBlockingQueue
如果容量满了,也不会扩容,所以一旦满了就无法再往里放数据了 。
- 首先我们从常用的方法出发,根据各自的特点我们可以大致分为三个大类,如下表所示:
IllegalStateException
异常 remove删除队列头节点当队列为空后,删除则抛出 NoSuchElementException
异常 element获取队列头元素当队列为空时,则抛出 NoSuchElementException
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Java线上CPU100% 问题排查
- 如何启用 GitHub Pages 中的子域名
- JavaScript,如何在字符串中找到一个字符?
- 支付宝app支付服务端的实现-Java版
- Mysql中你知道几种防止数据重复的方法?
- 有氧舞蹈的减肥方法
- 慢跑2小时的好处
- 马黛茶,阿根廷马黛茶,从茶叶中提取出的粗咖啡有绿色光泽
- 班章村的由来,2014年中茶普洱班章审评
- 职场pua|职场PUA在职场中已随处可见,不知不觉你已是受害者