首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

双向链表的阻塞队列LinkedBlockingDeque

今天学习阻塞队列中的最后一个类LinkedBlockingDeque。LinkedBlockingDeque简介

LinkedBlockingDeque与LinkedBlockingQueue功能很相似,不过LinkedBlockingQueue底层是单向链表,LinkedBlockingDeque是双向链表。所以LinkedBlockingDeque提供了更多的以First、Last结尾的方法,可以指定从队列的头部或者尾部获取、添加数据,而LinkedBlockingQueue只能把数据加到尾部,从头部获取数据。

基础介绍

LinkedBlockingDeque继承AbstractQueue并实现了BlockingDeque接口。BlockingDeque继承BlockingQueue,是对阻塞队列方法的扩展,对之前提到过的BlockingQueue中拥有的add、offer 、put、take、poll等基础方法均扩展,比如addFirst、addLast、offerFirst 、offerLast,putFirst、takeLast等方法。

其中以First结尾的方法表示插入、获取或移除队列的第一个元素。以Last结尾的方法表示插入、获取获移除队列的最后一个元素

基本数据结构

内部链表节点Node主要有三个属性:

E item:出入的元素,为null表示已经被消费;

Node prev:当前节点前一个节点,为null表示没有前节点;

Node next:当前节点下一个节点,为null表示没有后节点;

这种结构是最基本的双向链表结构了,单向链表就是没有prev属性。

关键属性如下图:

可以看到LinkedBlockingDeque与LinkedBlockingQueue几乎没有什么区别,主要属性基本一样。

关键方法

通过对几个add、offer 、put跟进源码发现他们最终调用的是linkLast方法,而这几个以Last结尾的方法调用的是linkFirst,所以我们直接看linkLast、linkFirst方法的源码,源码如下图:

方法还是比较简单的,总共就两步:

首先获取first或者last,设置当前的next或者prev,这样节点就加到链表中了

在判断first、last是否为null来判断当前队列是否为空,为空则更新last、first,不为null则更新first的prev或者last的next,就实现了双向链表;

同样从队列中获取移除的方法最终都是调用的unlinkFirst、unlinkLast方法,方法源码如下图:

unlink方法也是比较简单的,因为是从队列中把头结点或者尾结点移除,所以只需要获取对应节点,然后把它的next或者prev设置给first、last,那么这个节点就从链表中移除了,最后返回移除节点中的数据就行。

因为在调用link、unlink方法之前都已经获取了锁资源,所以这两类方法还是比较简单的。

总结

LinkedBlockingDeque整体来说都比较简单的了,它主要是新增一个一些方法可以灵活的向队列中插入、移除元素。

LinkedBlockingQueue队列只能先进先出,但是LinkedBlockingDeque通过多提供的方法可实现先进后出(消费者生产者都调用first或者last方法)。还可以在正常的先进先出情况下通过first或者last对一些特殊数据进行优先处理或者延后处理

Java程序员日常学习笔记,如理解有误欢迎各位交流讨论!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200924A0I87B00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券