什么是阻塞队列?
队列是我们常见的一种数据结构,特性就是FIFO(先进先出)。而阻塞队列,前面加了阻塞两个字,顾名思义就是对队列为空的时候,“取”操作会使队列block,“添加/存入”操作也会使队列block。
BlockingQueue是一个接口,我们所知道的实现类就有七个

这里我们并不打算介绍这些实现类的特性,而是要介绍他们的四组共同API。
四组API介绍
这里我们先用表格简单了解一下,下面再用实例代码来介绍。
方式 | 抛出异常 | 有返回值,不抛出异常 | 阻塞等待 | 超时等待 |
---|---|---|---|---|
添加元素 | add(e),满异常 | offer(e),满返回false | put(e),满等待 | offer(e,time,unit),满等待到超时 |
移除元素 | remove(),空异常 | poll(),空返回null | take(),空等待 | poll(time,unit),空等待到超时 |
获取队首元素 | element(),空异常 | peek(),空返回null | 无 | 无 |
(1)抛出异常的API
我们就初始化一个比较常用的ArrayBlockingQueue,测试一下第一组API

查看源码,我们知道add如果添加成功的话是会返回true的。

我们此时如果继续添加的话,不出意外就是会报异常的。

那么移除元素的话,我们也会上面也说道了,当出现为空的时候移除是会报空异常的。


查看队首元素的话

(2)有返回值,不抛出异常的API
第二组API的话,我们在未满和未空的时候的操作是一样的,但是在满了之后继续添加元素的话,它就不会抛出异常,而是添加失败返回一个false。

在为空的时候移除返回的是一个null。

查看队首元素

(3)阻塞时等待的API
我们在阻塞队列满的时候添加元素,会发现程序不会停止运行,而是会一直等待下去。同理,在为空的时候移除移除元素也会一直等待下去。这在我们开发的时候需要注意使用,以免程序一直等待下去。
因为put是没有返回值的,所以我们在执行完添加三个元素的时候,打印一下"添加完成!"

这个我们继续添加的话,是会一直等待下去的。所以我们在添加下面打印一个输出看看程序会不会执行到那里

可以看到,程序会一直阻塞在那里。而移除也是同样的操作和结果

(4)超时等待的API


总结
总结的话就是我上面的那一个表格,然后就是根据业务和场景需求来选择。
方式 | 抛出异常 | 有返回值,不抛出异常 | 阻塞等待 | 超时等待 |
---|---|---|---|---|
添加元素 | add(e),满异常 | offer(e),满返回false | put(e),满等待 | offer(e,time,unit),满等待到超时 |
移除元素 | remove(),空异常 | poll(),空返回null | take(),空等待 | poll(time,unit),空等待到超时 |
获取队首元素 | element(),空异常 | peek(),空返回null | 无 | 无 |
网友评论