ConcurrentLinkedQueue 的实现原理分析

ConcurrentLinkedQueue 是一个基于链接节点的无界线程安全队列,它采用先进先出FIFO的规则对节点进行排序,当我们添加一个元素的时候,它会添加到队列的尾部,当我们获取一个元素时,它会返回队列头部的元素。它采用了“wait-free”算法。并且采用CAS操作,保证数据的一致性。

CAS是compare and set的缩写,意思是指在set值之前先比较改值有没有变化,只有在没变化的情况下才对其赋值。

入队源码:

public boolean offer(E e) {
    //判断元素是否为空
    checkNotNull(e);

    //入队前,创建一个新节点
    final Node<E> newNode = new Node<E>(e);

    // 创建一个指向tail节点的引用
    // 用p来表示队列的尾节点
    for (Node<E> t = tail, p = t;;) {

        //获取p节点的下一个节点
        Node<E> q = p.next;
        if (q == null) {
            // q为null,表示p节点为尾节点,无下一个节点
            if (p.casNext(null, newNode)) {
                // 原子操作,如果下一个值为null,则next改变为newNode的值
                if (p != t) // 如果此时tail节点有大于等于1个节点,p节点不是tail节点,则将入队节点设置成tail节点。
                    casTail(t, newNode);  // 允许更新失败,如果失败表示有其他线程更新了tail节点。
                return true;
            }
            // Lost CAS race to another thread; re-read next
        }
        else if (p == q)
            // p==q 表示节点p已经从队列里移除。如果tail没有被修改,它也被从队列移除。
            // (可能当前队列中没有数据存在,所以返回head节点)
            p = (t != (t = tail)) ? t : head;
        else
            // 节点P仍然在队列上,且不是最后节点,p向前移
            // 在两跳之后检测tail的更新
            p = (p != t && t != (t = tail)) ? t : q;
    }
}

AtomicLong:对长整形进行原子操作。
在32位操作系统中,64位的long和double变量由于会被JVM当做两个分离的32位来进行操作,所以不具备原子性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值