什么是阻塞队列?
队列是我们常见的一种数据结构,特性就是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
无
无