Java并发编程的艺术:(6)Java 并发容器和框架之 ConcurrentLinkedQueue


在并发编程中,有时候需要使用线程安全的队列。如果要实现一个线程安全的队列有两种方式:一种是使用阻塞算法,另一种是使用非阻塞算法。使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入队和出队使用不同的锁)等方式来实现。非阻塞的实现方式则可以使用循环 CAS 的方式来实现。

ConcurrentLinkedQueue 是一个机遇链接节点的无界线程安全队列,它采用先进先出的规则对节点进行排序,当我们添加一个元素的时候,他会添加到队列的尾部;当我们获取一个元素时,它会返回队列头部的元素。它采用了 “wait-free” 算法(CAS)来实现,该算法在 Michael & Scott 算法基础上进行了一些修改。

ConcurrentLinkedQueue 的结构

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

private transient volatile Node<E> tail = head;

入队列

入队列就是将入队节点添加到队列的尾部。插入的过程就是数据结构中学习的队列的操作,不过这里边在 tail 节点插入时采用了 CAS 算法保证线程安全。

出队列

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

学过数据结构之后,这部分内容非常容易理解,ConcurrentLinkedQueue 跟普通的队列区别在于,为了保证并发下的线程安全,对队列的修改操作采用了 CAS 算法,仅此而已。

参考

《Java 并发编程的艺术》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值