中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中的AQS同步隊列問題怎么解決

發布時間:2022-06-07 13:43:08 來源:億速云 閱讀:143 作者:iii 欄目:開發技術

這篇文章主要介紹“Java中的AQS同步隊列問題怎么解決”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Java中的AQS同步隊列問題怎么解決”文章能幫助大家解決問題。

    AQS 同步隊列

    1、AQS 介紹

    AQSAbstractQueuedSynchronizer 的縮寫,他是一個抽象同步類,為 JUC 包下的大多數同步工具提供了核心實現,例如 ReentrantLock 的底層就是使用同步隊列。AQS 提供一套基礎的機制來實現線程的同步、阻塞與喚醒、等待隊列等功能,也就是想要深入學習線程工具類,這個同步隊列就必須得掌握。

    1.1、類圖關系

    下面是整個 AQS 的類結構實現(從源碼中直接打印的圖,平常學習源碼也可以這樣打印出來觀察整個程序的運行情況,有助于理解),從圖中我們不難發現 AQS 內部持有兩個 Node 類型的 headtail 屬性,我們在什么時候會接觸到頭尾節點的定義,大家都是有經驗的開發人員,肯定都能想到是鏈表當中。

    在屬性列中我們可以看見一個 state:int 這樣的一個狀態字段,Lock 的重入特性就是根據此來實現的,可以表示當前線程的鎖重入次數。整個類繼承自 AbstractOwnableSynchronizer 類,自然擁有對于其父類中屬性的一些控制權,而里面的 Thraed 的線程就是表示當前持有鎖的線程,在整個鎖過程中具有很重要的地位。

    Java中的AQS同步隊列問題怎么解決

    1.2、節點剖析

    當然鏈表只是一種組織存儲形式的一種數據結構,這里叫做 FIFO 雙向隊列,至于為什么是雙向的呢,看一下 Node 的節點定義就能明白,一個節點中含有 prevnext 節點來快速訪問前驅和后繼節點,不就是典型的雙向形式呢。

    相信大家在看到這個類字段的屬性名定義之后就能才出來其的作用,但是這里還是介紹一下主要的幾個字段含義,印證大家的猜想。

    屬性作用
    thread表示當前節點封裝的具體線程
    SHARED表示當前線程是獲取共享資源時被阻塞
    EXCLUSIVE表示當前線程是獲取獨占資源時被掛起
    prev當前節點的前驅節點
    next當前節點的后繼節點
    waitStatus記錄當前線程的等待狀態,其狀態取值就是下面的四個字段
    CANCELLED取消線程
    SIGNAL線程需要被喚醒
    CONDITION線程在 condition 中等待
    PROPAGATE釋放共享資源時需要通知其余節點線程

    2、AQS 實現原理

    上面我們知道了 AQS 其實就是一個雙向的隊列,如下圖的結構一樣。在線程獲取鎖失敗的情況下,會被封裝成一個 Node 節點而插入到隊列當中;當其他的線程釋放鎖之后又會從隊列中喚醒一個節點去爭搶鎖。

    Java中的AQS同步隊列問題怎么解決

    2.1、隊列初始化

    通過源碼我們可以發現,在 AQS 進行初始化的時候的并沒有對 headtail 進行初始化,而這兩個節點是控制整個隊列的,也就是說一開始整個隊列處于 null 狀態。

    protected AbstractQueuedSynchronizer() {}

    當第一個線程爭搶鎖失敗之后會封裝成 Node 進入到同步隊列當中,這個時候就會進行判斷,如果當前隊列為空就會進行初始化(未進行初始化),初始化完成之后就將當前線程節點接在隊列的尾部。

    private final void initializeSyncQueue() {
        Node h;
        if (HEAD.compareAndSet(this, (Void)null, h = new Node())) {
            this.tail = h;
        }
    }

    Java中的AQS同步隊列問題怎么解決

    2.2、追加節點

    追加節點的操作就是簡單的鏈表尾部添加節點的過程了,這里就不做過多的贅述。這里來看看前面初始化時會添加一個額外的節點在隊列中,其實這個節點就是代表當前已經獲取了鎖的線程,至于為什么這么設置,大家往后看就明白了。

    Java中的AQS同步隊列問題怎么解決

    3、AQS 喚醒動作

    在進行線程喚醒的過程中,會優先喚醒當前持有鎖線程的下一個節點線程。

    • head 指針指向下一個節點;

    • 原來頭結點的 next 指向 null;

    • 當前頭結點的 prev 指向 null;

    • 當前頭結點的 thread 指向 null。

    這樣就完成線程的喚醒操作了,但是這樣來講其實是不完美的,因為 AQS 只是一個抽象的統一工具,本身并沒有對業務進行規范,還是要結合具體的實現類,例如 ReentrantLockCountDownLatchCyclicBarrier 這些的執行過程來進行分析。

    Java中的AQS同步隊列問題怎么解決

    關于“Java中的AQS同步隊列問題怎么解決”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    东乌珠穆沁旗| 石阡县| 滨海县| 辽中县| 马尔康县| 增城市| 龙游县| 南城县| 广饶县| 响水县| 中超| 元谋县| 蒙阴县| 乌拉特中旗| 巫溪县| 孝感市| 河池市| 南澳县| 方正县| 横山县| 博爱县| 曲阜市| 临猗县| 大丰市| 武宁县| 尉氏县| 莱州市| 九台市| 介休市| 尼勒克县| 包头市| 轮台县| 社会| 成都市| 巩义市| 张家口市| 崇明县| 木兰县| 吴旗县| 开封县| 固安县|