成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ConditionObject源碼閱讀

xietao3 / 3500人閱讀

摘要:前言本來準備做源碼閱讀的幾千行看著太累了看了幾篇大神的文章后才基本搞懂附在這里閱讀本文前請先看懂的介紹和原理分析并發(fā)包源碼學習之框架四源碼分析接口實現(xiàn)接口一般看一個類實現(xiàn)的接口可以看出它的目的其實也是熟悉的目的主要是替代的方法的它是基于實現(xiàn)

前言

本來準備做AbstractQueuedSynchronizer源碼閱讀的,幾千行看著太累了,看了幾篇大神的文章后才基本搞懂,附在這里,閱讀本文前請先看懂AQS

AbstractQueuedSynchronizer的介紹和原理分析

Java并發(fā)包源碼學習之AQS框架(四)AbstractQueuedSynchronizer源碼分析

Condition接口

ConditionObeject實現(xiàn)Condition接口,一般看一個類實現(xiàn)的接口可以看出它的目的,其實也是熟悉API.
Condition的目的主要是替代Object的wait,notify,notifyAll方法的,它是基于Lock實現(xiàn)的.(而Lock是來替代synchronized方法).

API
public interface Condition {

     /** 
      * 暫停此線程直至一下四種情況發(fā)生
      * 1.此Condition被signal()
      * 2.此Condition被signalAll()
      * 3.Thread.interrupt()
      * 4.偽wakeup
      * 以上情況.在能恢復方法執(zhí)行時,當前線程必須要能獲得鎖
      */
    void await() throws InterruptedException;

 
    //跟上面類似,不過不響應中斷
    void awaitUninterruptibly();

    //帶超時時間的await()
    long awaitNanos(long nanosTimeout) throws InterruptedException;

    //帶超時時間的await()
    boolean await(long time, TimeUnit unit) throws InterruptedException;
    
    //帶deadline的await()
    boolean awaitUntil(Date deadline) throws InterruptedException;

    //喚醒某個等待在此condition的線程
    void signal();
  
    //喚醒所有等待在此condition的所有線程
    void signalAll();
}
AQS中的ConditionObject

此類的構(gòu)造方法沒有參數(shù),所以不用講
整體講下這個ConditionObject的實現(xiàn),其實其維護兩個隊列,

Condition隊列,表示等待的隊列,其waitStatus=Node.Condition,由firstWaiter和lastWaiter兩個屬性操控.

Sync隊列,表示可以競爭鎖的隊列,這個跟AQS一致,waitStatus=0;

await()方法呢就是把當前線程創(chuàng)建一個Node加入Condition隊列,接著就一致循環(huán)查其在不在Sync隊列,如果當前節(jié)點在Sync隊列里了,就可以競爭鎖,恢復運行了.

signal()方法就是把某個節(jié)點的nextWaiter設為null,再把其從Condition隊列轉(zhuǎn)到Sync隊列.
具體細節(jié)看下面源碼及注釋:

await()方法
  /**
   * 暫停此線程,直至許可滿足
   * 只看沒有中斷和超時的await方法,其它處理中斷和超時的邏輯不care   
   */
  public final void awaitUninterruptibly() {
    
            Node node = addConditionWaiter();
            //釋放當前線程的鎖
            int savedState = fullyRelease(node);
            boolean interrupted = false;
            //看自己在不在等待隊列,在
            while (!isOnSyncQueue(node)) {
                //為了線程調(diào)度,禁用當前的線程,直到許可可用
                LockSupport.park(this);
                if (Thread.interrupted())
                    interrupted = true;
            }
            //獲取剛才釋放的鎖,參考AQS中acquire的講解吧
            if (acquireQueued(node, savedState) || interrupted)
                selfInterrupt();
        }
        
  /**
   * 添加一個等待Node到隊列中   
   */
  private Node addConditionWaiter() {
            Node t = lastWaiter;
            // 如果尾節(jié)點被取消了,清理掉
            if (t != null && t.waitStatus != Node.CONDITION) {
                unlinkCancelledWaiters();
                t = lastWaiter;
            }
            // 新建一個Condition狀態(tài)的節(jié)點,并將其加在尾部
            Node node = new Node(Thread.currentThread(), Node.CONDITION);
            if (t == null)
                firstWaiter = node;
            else
                t.nextWaiter = node;
            lastWaiter = node;
            return node;
        }
        
  /**
   * 釋放當前的state,最終還是調(diào)用tryRelease方法
   */
  final int fullyRelease(Node node) {
        boolean failed = true;
        try {
            int savedState = getState();
            if (release(savedState)) {
                failed = false;
                return savedState;
            } else {
                throw new IllegalMonitorStateException();
            }
        } finally {
            if (failed)
                node.waitStatus = Node.CANCELLED;
        }
    }
    
  /**
   * 是否還需要等待
   */
  final boolean isOnSyncQueue(Node node) {
        //如果狀態(tài)為Node.CONDITION,即還在Condition隊列中,還得再循環(huán)中等待
        //如果其waitStatus不為Node.CONDITION,其前置節(jié)點,即Sync的前置節(jié)點為null,為啥也繼續(xù)等著呢???誰來解答我的疑問
        if (node.waitStatus == Node.CONDITION || node.prev == null)
            return false;
        //如果狀態(tài)不為Node.CONDITION,即不在Condition隊列了,有前置節(jié)點也有后置節(jié)點,那么其一定在Sync隊列
        if (node.next != null) 
            return true;
        /*
         * 其前置節(jié)點為非null,但是也不在Sync也是可能的,因為CAS將其加入隊列失敗.所以我們需要從尾部開始遍歷確保其在隊列
         */
        return findNodeFromTail(node);
    }
    /
    
    /**
     * 從尾部查找node節(jié)點
     */
    private boolean findNodeFromTail(Node node) {
        Node t = tail;
        for (;;) {
            if (t == node)
                return true;
            if (t == null)
                return false;
            t = t.prev;
        }
    }
signal()
/**
 * 釋放信號
 */
 public final void signal() {
            //如果不是排它模式,則拋出IllegalMonitorStateException異常
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
            //將等待隊列的第一個節(jié)點出隊列,并將其加入AQS的鎖隊列
            Node first = firstWaiter;
            if (first != null)
                doSignal(first);
 }
 
/**
 * 真正的釋放信號
 */
private void doSignal(Node first) {
            do {
                //講first的nextWaiter設為null
                if ( (firstWaiter = first.nextWaiter) == null)
                    lastWaiter = null;
                first.nextWaiter = null;
            }
            // 如果轉(zhuǎn)換隊列不成功且等待隊列不為null,繼續(xù)do
            while (!transferForSignal(first) &&
                     (first = firstWaiter) != null);
}

/**
 * 將一個節(jié)點從condition隊列轉(zhuǎn)換到Sync隊列
 */
final boolean transferForSignal(Node node) {
        //所謂的Condition隊列和Sync隊列就在于waitStatus值
        if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
            return false;
        Node p = enq(node);
        int ws = p.waitStatus;
        if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
            LockSupport.unpark(node.thread);
        return true;
}

/**
 * 喚醒所有等待在此condition的所有線程
 */
public final void signalAll() {
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
            Node first = firstWaiter;
            if (first != null)
                doSignalAll(first);
}

/**
 * 遍歷所有節(jié)點,使其加入到Sync隊列
 */
private void doSignalAll(Node first) {
            lastWaiter = firstWaiter = null;
            do {
                Node next = first.nextWaiter;
                first.nextWaiter = null;
                transferForSignal(first);
                first = next;
            } while (first != null);
    }

在此輸入正文

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/70093.html

相關文章

  • Java多線程框架源碼閱讀之---AQS的ConditionObject

    摘要:前置文章為,如果不了解的基本和實現(xiàn)機制,建議先看一下這個文章。類似于和,常用于實現(xiàn)生產(chǎn)者消費者。以下代碼是一個用的做的一個生產(chǎn)者消費者例子。 前置文章為https://segmentfault.com/a/11...,如果不了解AQS的基本lock和unlock實現(xiàn)機制,建議先看一下這個文章。 Condition類似于wait和notify,notifyAll,常用于實現(xiàn)生產(chǎn)者消費者。...

    Tonny 評論0 收藏0
  • AbstractQueuedSynchronizer 原理分析 - Condition 實現(xiàn)原理

    摘要:實現(xiàn)原理是通過基于單鏈表的條件隊列來管理等待線程的。中斷在轉(zhuǎn)移到同步隊列期間或之后發(fā)生,此時表明有線程正在調(diào)用轉(zhuǎn)移節(jié)點。在該種中斷模式下,再次設置線程的中斷狀態(tài)。 1. 簡介 Condition是一個接口,AbstractQueuedSynchronizer 中的ConditionObject內(nèi)部類實現(xiàn)了這個接口。Condition聲明了一組等待/通知的方法,這些方法的功能與Objec...

    leone 評論0 收藏0
  • AbstractQueuedSynchronizer 原理分析 - Condition 實現(xiàn)原理

    摘要:實現(xiàn)原理是通過基于單鏈表的條件隊列來管理等待線程的。中斷在轉(zhuǎn)移到同步隊列期間或之后發(fā)生,此時表明有線程正在調(diào)用轉(zhuǎn)移節(jié)點。在該種中斷模式下,再次設置線程的中斷狀態(tài)。 1. 簡介 Condition是一個接口,AbstractQueuedSynchronizer 中的ConditionObject內(nèi)部類實現(xiàn)了這個接口。Condition聲明了一組等待/通知的方法,這些方法的功能與Objec...

    李世贊 評論0 收藏0
  • AbstractQueuedSynchronizer 原理分析 - Condition 實現(xiàn)原理

    摘要:實現(xiàn)原理是通過基于單鏈表的條件隊列來管理等待線程的。中斷在轉(zhuǎn)移到同步隊列期間或之后發(fā)生,此時表明有線程正在調(diào)用轉(zhuǎn)移節(jié)點。在該種中斷模式下,再次設置線程的中斷狀態(tài)。 1. 簡介 Condition是一個接口,AbstractQueuedSynchronizer 中的ConditionObject內(nèi)部類實現(xiàn)了這個接口。Condition聲明了一組等待/通知的方法,這些方法的功能與Objec...

    bigdevil_s 評論0 收藏0
  • 源碼分析JDK8之AbstractQueuedSynchronizer

    摘要:與之相關的方法有三個原子性地修改都是類型,可見我們可以進行,來定義的獲取與釋放從而實現(xiàn)我們自定義的同步器。 前言 源碼分析我認為主要有兩個作用:滿足好奇心,我想每一個有追求的人都不會滿足于僅僅做一個API Caller實現(xiàn)功能就好,我們也想知道它到底是怎么實現(xiàn)的;借鑒與升華,當我們明白了一個類的設計原理,在一定的情境下我們可以借鑒其設計哲學,甚至針對我們自己特殊的業(yè)務場景對其進行改良與...

    魏憲會 評論0 收藏0

發(fā)表評論

0條評論

xietao3

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<