java并发之ConcurrentLinkedQueue

本文探讨了线程安全队列的两种实现方式:阻塞算法与非阻塞算法。详细解析了ConcurrentLinkedQueue的内部工作原理,包括offer()方法的流程,以及通过CAS实现的wait-free算法。

实现一个线程安全的队列有两种方式,一种是阻塞算法,另一种是非阻塞算法。使用阻塞算法有两种方式:两把锁(出队和入队采用不同的锁),或者出队入队采用同一把锁。而非阻塞算法可以采用循环CAS的方式来实现。ConcurrentLinkedQueue采用基于链接节点的无界安全队列来实现,采用wait-free算法(即CAS)来实现。

offer()方法
public boolean offer(E e) {
    checkNotNull(e);
    final Node<E> newNode = new Node<E>(e);

    for (Node<E> t = tail, p = t;;) {
        Node<E> q = p.next;
        if (q == null) {
            // p为最后节点,直接赋值
            if (p.casNext(null, newNode)) {//0
                //如果p!=t说明tail节点不是最后节点,直接赋值为最新节点
                if (p != t) 
                    casTail(t, newNode);//1
                return true;
            }
        }
        else if (p == q)
            //p==q时,将p赋值head节点或者t()
            p = (t != (t = tail)) ? t : head;//2
        else
            //将p赋值为最后节点在进行加入
            p = (p != t && t != (t = tail)) ? t : q;//3
    }
}

一个空队列依次加入1、2、3、4的过程如下:

  • 加入第1个元素1时,此时tail和head节点都为null,next也为null。由于p==p.next,直接执行第0步进行赋值。赋值完成后head节点为1,next为null;tail节点仍为null,next节点指向自身。
  • 加入第2个元素2时,由于tail节点的next指向自身所以p==q且p!=null,此时先执行第2步将p=head,此时排为最后节点,然后执行第0步和第1步,将newNode加到队尾,将tail节点指向队尾。
  • 加入第3个元素3时tail.next==null,直接执行第0步赋值。
  • 加入第四个元素4时,tail.next!=null&&tail!=tail.next,此时执行第3步p=p.next,然后分别执行第0、1步。
    注意tail节点并不总是指向最后一个节点,head节点在第一次offer()之后指向第一个节点。

转载于:https://www.cnblogs.com/EndOfTheWorld/p/9796130.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值