看看ConcurrentLinkedQueue源码 in Java 9

看ConcurrentLinkedQueue这个名字,应该叫并发链表队列哈。

ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,它采用先进先出的规则对节点进行排序,当我们添加一个元素的时候,它会添加到队列的尾部,当我们获取一个元素时,它会返回队列头部的元素。

ConcurrentLinkedQueue由head节点和tair节点组成,每个节点(Node)由节点元素(item)和指向下一个节点的引用(next)组成,节点与节点之间就是通过这个next关联起来,从而组成一张链表结构的队列。默认情况下head节点存储的元素为空,tair节点等于head节点。

当许多线程共享对公共集合的访问权限时,ConcurrentLinkedQueue是一个合适的选择。与大多数其他并发集合实现一样,此类不允许使用null元素。

该实现采用有效的非阻塞算法,该算法基于Maged M.Michael和Michael L.Scott提出的 Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms 中描述的算法。

迭代器是弱一致的,在迭代器创建时或之后的某个时刻返回反映队列状态的元素。它们不会抛出ConcurrentModificationException,并且可能与其他操作同时进行。

常用的并发队列有阻塞队列和非阻塞队列,前者使用锁实现,后者则使用CAS非阻塞算法实现,使用非阻塞队列一般性能比较好。

下面看看这个类的构造方法:

方法的实现:

扫描二维码关注公众号,回复: 3550004 查看本文章

  • 无参的构造方法,构建一个空的ConcurrentLinkedQueue,head和tail设置为Node(null)
  • 创建一个ConcurrentLinkedQueue,最初包含给定集合的元素,以集合迭代器的遍历顺序添加。迭代中用了Node<E> h = null, t = null;两个变量来帮助迭代,这里设置值用了 UNSAFE.putOrderedObject(this, nextOffset, val);

这里要先说一下链表结构实现的两个关键字段 head与tail,是用private transient volatile修饰:

可以看到这两个值是 Node,这个类的实现也比较关键。这里有两个属性E item,和Node<E> next,对值得的操作用了sun.misc.Unsafe UNSAFE里的方法实现。Node分别用来存在列表的首尾节点,其中head节点存放链表第一个item为null的节点,tail则并不是总指向最后一个节点。Node节点内部则维护一个变量item用来存放节点的值,next用来存放下一个节点,从而链接为一个单向无界列表。

然后就是具体应用到相应的队列的方法里,比如offer方法的实现,将指定元素插入此队列的尾部。第一是定位出尾节点,第二是使用CAS算法能将入队节点设置成尾节点的next节点,如不成功则重试:

tail节点并不总是尾节点,所以每次入队都必须先通过tail节点来找到尾节点,尾节点可能就是tail节点,也可能是tail节点的next节点。代码中循环体中的第一个if就是判断tail是否有next节点,有则表示next节点可能是尾节点。

然后还有poll方法的实现,检索并删除此队列的头部,如果此队列为空,则返回null。并不是每次出队时都更新head节点,当head节点里有元素时,直接弹出head节点里的元素,而不会更新head节点。只有当head节点里没有元素时,出队操作才会更新head节点:

首先获取头节点的元素,然后判断头节点元素是否为空,如果为空,表示另外一个线程已经进行了一次出队操作将该节点的元素取走,如果不为空,则使用CAS的方式将头节点的引用设置成null,如果CAS成功,则直接返回头节点的元素,如果不成功,表示另外一个线程已经进行了一次出队操作更新了head节点,导致元素发生了变化,需要重新获取头节点。

peek()方法的实现,检索但不移除此队列的头部,如果此队列为空,则返回null。

这里size()方法的实现,返回此队列中的元素数。与大多数集合不同,size方法不是constant-time操作。由于这些队列的异步性质,确定元素的当前数量需要遍历元素,因此如果在遍历期间修改此集合,则可能会报告不准确的结果。

还有remove方法的实现,如果队列里面存在该元素则删除给元素,如果存在多个则删除第一个,并返回true,否者返回false

发现一篇Importnew写的不错的博文:http://www.importnew.com/25668.html 对各种情况还画了图

有什么讨论的内容,可以加我公众号:

猜你喜欢

转载自blog.csdn.net/woshiyexinjie/article/details/82756375
今日推荐