为了账号安全,请及时绑定邮箱和手机立即绑定

JDK 源码理解问题

JDK 源码理解问题

繁星coding 2019-03-22 14:15:17
小弟最近在翻看JDK的源码但是奈何基础太差有一处始终想不通。希望大家帮忙解答下共同进步。ConcurrentLinkedQueue的源码中的offer方法 (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 is last node                if (p.casNext(null, newNode)) {                    // Successful CAS is the linearization point                    // for e to become an element of this queue,                    // and for newNode to become "live".                    if (p != t) // hop two nodes at a time                        casTail(t, newNode);  // Failure is OK.                    return true;                }                // Lost CAS race to another thread; re-read next            }            )我的理解是 既然t = p; 那么对p的操作应该等同与对t的操作,那么将newNode设置为p.next不久等同于对t也设置next属性么, 为什么p!=t呢?
查看完整描述

2 回答

?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

就一个线程在处理的话肯定不会走casTail这句,如果有多个线程呢?


    public boolean offer(E e) {

        checkNotNull(e);

        final Node<E> newNode = new Node<E>(e);


        for (Node<E> t = tail, p = t;;) {

             //如果2个线程到这里,一个先把流程走完了

             //第二个线程的q开始执行的时候已经不是null了

             //所以会走else的分支,修改了p和t的关系

            Node<E> q = p.next;

            if (q == null) {

                // p is last node

                if (p.casNext(null, newNode)) {

                    // Successful CAS is the linearization point

                    // for e to become an element of this queue,

                    // and for newNode to become "live".

                    if (p != t) // hop two nodes at a time

                        casTail(t, newNode);  // Failure is OK.

                    return true;

                }

                // Lost CAS race to another thread; re-read next

            }

            else if (p == q)

                // We have fallen off list.  If tail is unchanged, it

                // will also be off-list, in which case we need to

                // jump to head, from which all live nodes are always

                // reachable.  Else the new tail is a better bet.

                p = (t != (t = tail)) ? t : head;

            else

                // Check for tail updates after two hops.

                p = (p != t && t != (t = tail)) ? t : q;

        }

    }


查看完整回答
反对 回复 2019-04-26
?
ibeautiful

TA贡献1993条经验 获得超5个赞

当两个线程同时 进入 q == null 判断逻辑的时候 ,其中一个线程完成了CAS操作以后,另一个线程会重新循环,这时候会走到 p = (p != t && t != (t = tail)) ? t : q; 这个操作 (ide中 是走到了 else if (p == q) 这个操作 , 不知道eclispe 和 idea为啥最终进入的方法不一样,希望高人能解答下),这时候p重新赋值了,然后 继续循环 到 q == null 这个逻辑,这时候p!=t 了 .


查看完整回答
反对 回复 2019-04-26
  • 2 回答
  • 0 关注
  • 575 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信