1

在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口、ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue,本文为系列文章第七篇。

BlockingDeque接口和BlockingQueue 接口一样都是在java.util.concurrent中定义的,它代表了一个线程安全的“双端队列”,以线程安全的方式向队列中添加元素或获取元素。本篇文章将带大家进一步了解BlockingDeque

deque是 "Double Ended Queue "的缩写。因此“双端队列”的含义就是可以从两端(队首或队尾)插入和取出元素的队列。

如果某个线程既生产又消费同一个队列的元素,那么就可以使用BlockingDeque双端队列。如果生产线程需要在队列的两端插入,而消费线程需要从队列的两端删除,也可以只使用BlockingDeque双端队列。参考下面的图进行理解

一个线程生产元素并将它们插入到队列两端中的任何一端。如果BlockingDeque当前是满的,插入线程将被阻塞,直到移除线程从BlockingDeque中取出一个元素。如果BlockingDeque当前为空,那么移除线程将被阻塞,直到插入线程将一个元素插入到BlockingDeque中。

BlockingDeque 方法

BlockingDeque有4组不同的方法,用于插入、删除和检查deque中的元素。每组方法在所要求的操作不能被立即执行的情况下表现也有所不同。参考下面的表格

队首操作抛出异常返回特定值阻塞后一直等待阻塞后等待超时
插入对象addFirst(o)offerFirst(o)putFirst(o)offerFirst(o, timeout, timeunit)
移除对象removeFirst(o)pollFirst()takeFirst()pollFirst(timeout, timeunit)
检查对象存在getFirst()peekFirst()
队尾操作抛出异常返回特定值阻塞后一直等待阻塞后等待超时
插入对象addLast(o)offerLast(o)putLast(o)offerLast(o, timeout, timeunit)
移除对象removeLast(o)pollLast()takeLast()pollLast(timeout, timeunit)
检查对象存在getLast()peekLast()

大家可以看到,这些方法和和BlockingQueue 的方法有些相似,只是在方法的基础上加了xxxFirst和xxxLast,所以可以参考我之前的文章对比学习),上面的方法的四种行为分别的含义是

  1. 抛出异常: 如果调用方法后不能立即响应结果(空队列或满队列),则抛出异常。
  2. 返回特定值: 如果调用方法后不能立即响应结果(空队列或满队列),则返回特定的值(通常是true/false),true表示方法执行成功,否则表示方法执行失败。
  3. 阻塞后一直等待: 如果调用方法后不能立即响应结果(空队列或满队列),该方法将被阻塞一直处于等待状态。
  4. 阻塞后等待超时: 如果调用方法后不能立即响应结果(空队列或满队列),该方法将在一定时间范围内被阻塞等待,也就是在超时时间范围内阻塞。当超出超时时间之后,方法线程将不再阻塞,而是返回一个特定的值(通常是true/false),true表示方法执行成功,否则表示方法执行失败。

BlockingDeque继承BlockingQueue

BlockingDeque接口继承了BlockingQueue接口。这意味着你可以将BlockingDeque作为一个BlockingQueue使用。如果你这样做,各种插入方法将把元素添加到deque的末尾,而移除方法将从deque的队首移除元素。BlockingQueue接口的插入和删除方法,就是这样做的。

下面是BlockingQueue的方法在BlockingDeque实现中的作用对照表

BlockingQueueBlockingDeque
add()addLast()
offer()offerLast()
put()putLast()
remove()removeFirst()
pollpollFirst()
take()takeFirst()
element()getFirst()
peek()peekFirst()

BlockingDeque 接口实现类

BlockingDeque是一个接口,所以当我们真正对它进行实例化的时候,需要使用它的接口实现类。在java.util.concurrent包中的LinkedBlockingDeque方法实现了BlockingDeque接口。

其使用方法也与BlockingQueue 大同小异,所以此处只做简单的介绍。

//初始化一个LinkedBlockingDeque
BlockingDeque<String> deque = new LinkedBlockingDeque<String>();

deque.addFirst("1");//向队首添加元素
deque.addLast("2"); //向队尾添加元素

String two = deque.takeLast(); //从队尾获取元素
String one = deque.takeFirst(); //从队首获取元素

欢迎关注我的博客,里面有很多精品合集

本文转载注明出处(必须带连接,不能只转文字):字母哥博客 - zimug.com

觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。


字母哥博客
933 声望1.5k 粉丝