亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

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條經驗 獲得超6個贊

當兩個線程同時 進入 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 關注
  • 600 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號