最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java之AQS(AbstractQueuedSynchronizer)用法解讀

 更新時(shí)間:2026年01月04日 10:52:53   作者:夏子曦  
AQS是Java并發(fā)包中的核心組件,用于構(gòu)建鎖和其他同步器,它通過(guò)同步狀態(tài)管理和FIFO隊(duì)列實(shí)現(xiàn)線程的排隊(duì)和喚醒機(jī)制,AQS支持獨(dú)占和共享兩種資源共享方式,并廣泛應(yīng)用于各種同步器的實(shí)現(xiàn)中

AQS(AbstractQueuedSynchronizer)是Java并發(fā)包(java.util.concurrent)中的一個(gè)核心組件,是構(gòu)建鎖和其他同步器的基礎(chǔ)框架。

以下是對(duì)AQS的詳細(xì)理解:

一、AQS的基本概念

AQS,全稱(chēng)為AbstractQueuedSynchronizer,是一個(gè)抽象的隊(duì)列式同步器。

它定義了一套多線程訪問(wèn)共享資源的同步器框架,為Java并發(fā)同步組件提供統(tǒng)一的底層支持。

AQS是一個(gè)為各個(gè)同步組件提供基本框架的抽象類(lèi),其內(nèi)部實(shí)現(xiàn)了同步狀態(tài)的管理和線程的排隊(duì)機(jī)制。

二、AQS的核心組件

  1. 同步狀態(tài):AQS使用一個(gè)int類(lèi)型的成員變量來(lái)表示同步狀態(tài)。這個(gè)狀態(tài)變量是線程共享的資源,通過(guò)內(nèi)置的FIFO隊(duì)列(先進(jìn)先出隊(duì)列)來(lái)完成獲取資源線程的排隊(duì)工作。
  2. FIFO隊(duì)列:AQS的底層實(shí)現(xiàn)是一個(gè)雙向鏈表,用于管理等待獲取同步狀態(tài)的線程。當(dāng)線程無(wú)法獲取同步狀態(tài)時(shí),會(huì)被加入到這個(gè)隊(duì)列中等待。
  3. CLH隊(duì)列鎖:AQS使用CLH隊(duì)列鎖來(lái)實(shí)現(xiàn)線程的阻塞等待和喚醒機(jī)制。CLH是一個(gè)虛擬的雙向隊(duì)列,即不存在隊(duì)列實(shí)例,僅存在節(jié)點(diǎn)之間的關(guān)聯(lián)關(guān)系。

三、AQS的工作原理

  1. 獲取同步狀態(tài):當(dāng)線程嘗試獲取同步狀態(tài)時(shí),會(huì)調(diào)用AQS的tryAcquire方法(對(duì)于獨(dú)占模式)或tryAcquireShared方法(對(duì)于共享模式)。如果成功獲取到同步狀態(tài),則返回true;否則,線程會(huì)被加入到等待隊(duì)列中。
  2. 釋放同步狀態(tài):當(dāng)線程釋放同步狀態(tài)時(shí),會(huì)調(diào)用AQS的tryRelease方法(對(duì)于獨(dú)占模式)或tryReleaseShared方法(對(duì)于共享模式)。這些方法會(huì)修改同步狀態(tài)的值,并可能喚醒等待隊(duì)列中的線程。
  3. 線程排隊(duì)與喚醒:等待獲取同步狀態(tài)的線程會(huì)被加入到FIFO隊(duì)列中,并按照隊(duì)列的順序等待。當(dāng)某個(gè)線程釋放同步狀態(tài)時(shí),會(huì)喚醒隊(duì)列中的下一個(gè)線程來(lái)嘗試獲取同步狀態(tài)。

四、AQS的資源共享方式

AQS支持兩種資源共享方式:獨(dú)占(Exclusive)和共享(Share)。

  1. 獨(dú)占:只有一個(gè)線程能執(zhí)行,如ReentrantLock。獨(dú)占鎖又可分為公平鎖和非公平鎖。公平鎖按照線程在隊(duì)列中的排隊(duì)順序來(lái)獲取鎖,非公平鎖則允許線程無(wú)視隊(duì)列順序直接去搶鎖。
  2. 共享:多個(gè)線程可同時(shí)執(zhí)行,如Semaphore、CountDownLatch、CyclicBarrier等。共享鎖允許多個(gè)線程同時(shí)訪問(wèn)共享資源。

五、AQS的應(yīng)用場(chǎng)景

AQS廣泛應(yīng)用于Java并發(fā)編程中,是實(shí)現(xiàn)各種同步機(jī)制的基礎(chǔ)。

例如,ReentrantLock、Semaphore、CountDownLatch等同步器都是基于AQS實(shí)現(xiàn)的。

通過(guò)擴(kuò)展AQS,開(kāi)發(fā)者可以實(shí)現(xiàn)各種復(fù)雜的同步器,以滿足不同的并發(fā)編程需求。

六、AQS的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

  1. 提供了統(tǒng)一的同步器框架,簡(jiǎn)化了同步器的實(shí)現(xiàn)過(guò)程。
  2. 使用了FIFO隊(duì)列來(lái)管理等待線程,保證了線程的公平性。
  3. 提供了靈活的資源共享方式,支持獨(dú)占和共享兩種模式。

缺點(diǎn)

  1. AQS是一個(gè)相對(duì)復(fù)雜的框架,需要開(kāi)發(fā)者對(duì)其內(nèi)部機(jī)制有一定的了解才能正確使用。
  2. 在某些情況下,AQS的性能可能不如一些定制的同步器。

七、AQS示例

import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.LockSupport;

// 自定義鎖類(lèi)
class MyLock implements Lock {
    // 靜態(tài)內(nèi)部類(lèi),繼承AQS
    private static class Sync extends AbstractQueuedSynchronizer {
        // 是否處于獨(dú)占模式
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }

        // 嘗試獲取鎖,當(dāng)狀態(tài)為0時(shí)獲取鎖成功
        public boolean tryAcquire(int acquires) {
            assert acquires == 1; // 只允許獲取1個(gè)單位的鎖
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        // 嘗試釋放鎖,將狀態(tài)設(shè)置為0
        protected boolean tryRelease(int releases) {
            assert releases == 1; // 只允許釋放1個(gè)單位的鎖
            if (getState() == 0) throw new IllegalMonitorStateException();
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        // 提供條件變量
        Condition newCondition() { return new ConditionObject(); }
    }

    // 將操作代理到Sync上
    private final Sync sync = new Sync();

    // 實(shí)現(xiàn)Lock接口的方法
    @Override
    public void lock() {
        sync.acquire(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    @Override
    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireNanos(unit.toNanos(time));
    }

    @Override
    public void unlock() {
        sync.release(1);
    }

    @Override
    public Condition newCondition() {
        return sync.newCondition();
    }

    public static void main(String[] args) {
        MyLock lock = new MyLock();

        Runnable task = () -> {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + " 獲取鎖");
                // 模擬任務(wù)執(zhí)行
                LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
            } finally {
                System.out.println(Thread.currentThread().getName() + " 釋放鎖");
                lock.unlock();
            }
        };

        Thread t1 = new Thread(task, "Thread-1");
        Thread t2 = new Thread(task, "Thread-2");

        t1.start();
        t2.start();
    }
}

MyLock類(lèi)

  • 實(shí)現(xiàn)Lock接口,內(nèi)部包含一個(gè)靜態(tài)內(nèi)部類(lèi)Sync,該內(nèi)部類(lèi)繼承自AbstractQueuedSynchronizer

Sync類(lèi)

  • isHeldExclusively:判斷當(dāng)前線程是否持有鎖。
  • tryAcquire:嘗試獲取鎖,如果當(dāng)前狀態(tài)為0(表示鎖未被持有),則通過(guò)compareAndSetState方法將狀態(tài)設(shè)置為1,并設(shè)置當(dāng)前線程為獨(dú)占線程。
  • tryRelease:嘗試釋放鎖,將狀態(tài)設(shè)置為0,并清除獨(dú)占線程。
  • newCondition:創(chuàng)建一個(gè)條件變量。

MyLock方法

  • Lock接口的方法代理到Sync對(duì)象上。

main方法

  • 創(chuàng)建兩個(gè)線程,每個(gè)線程嘗試獲取和釋放鎖,模擬任務(wù)執(zhí)行。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Jersey框架的統(tǒng)一異常處理機(jī)制分析

    Jersey框架的統(tǒng)一異常處理機(jī)制分析

    初學(xué)者往往不清楚java的異常為什么會(huì)設(shè)計(jì)成這個(gè)樣子,他們通常會(huì)對(duì)異常只進(jìn)行簡(jiǎn)單的處理
    2016-07-07
  • Java圖形界面開(kāi)發(fā)之簡(jiǎn)易記事本

    Java圖形界面開(kāi)發(fā)之簡(jiǎn)易記事本

    這篇文章主要為大家詳細(xì)介紹了Java圖形界面開(kāi)發(fā)之簡(jiǎn)易記事本的制作方法,,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • java實(shí)現(xiàn)MD5加密方法匯總

    java實(shí)現(xiàn)MD5加密方法匯總

    本文給大家匯總介紹了2種java實(shí)現(xiàn)MD5加密的方法,非常的實(shí)用,這里分享給大家,學(xué)習(xí)下其中的思路,對(duì)大家學(xué)習(xí)java非常有幫助。
    2015-10-10
  • 使用java代碼獲取新浪微博應(yīng)用的access token代碼實(shí)例

    使用java代碼獲取新浪微博應(yīng)用的access token代碼實(shí)例

    這篇文章主要介紹了使用java代碼獲取新浪微博應(yīng)用的access token實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • 匯總Java中List 去重的 6 種方法

    匯總Java中List 去重的 6 種方法

    這篇文章主要介紹了匯總Java中List 去重的 6 種方法,文章圍繞主題展開(kāi)List去重的方法,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-05-05
  • Java中常用輸出方式(print() println() printf())

    Java中常用輸出方式(print() println() printf())

    這篇文章主要介紹了Java中常用輸出方式(print() println() printf()),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Java線程之程安全與不安全代碼示例

    Java線程之程安全與不安全代碼示例

    這篇文章主要介紹了Java線程之程安全與不安全代碼示例,還是比較不錯(cuò)的,這里分享給大家,供需要的朋友參考。
    2017-11-11
  • SpringBoot項(xiàng)目讀取外置logback配置文件的問(wèn)題及解決

    SpringBoot項(xiàng)目讀取外置logback配置文件的問(wèn)題及解決

    SpringBoot項(xiàng)目讀取外置logback配置文件的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Java基礎(chǔ)之MapReduce框架總結(jié)與擴(kuò)展知識(shí)點(diǎn)

    Java基礎(chǔ)之MapReduce框架總結(jié)與擴(kuò)展知識(shí)點(diǎn)

    本章,是MapReduce的最終章,我在寫(xiě)本章的時(shí)候,發(fā)現(xiàn)前面忘記介紹MpaTask與ReduceTask了,所以本章補(bǔ)上哈,另外還有兩個(gè)擴(kuò)展的知識(shí)點(diǎn),講完這些,我會(huì)對(duì)整個(gè)MapReduce進(jìn)行總結(jié)一下,讓大家再次了解MapReduce的工作流程,更加清晰地認(rèn)識(shí)MapReduce ,需要的朋友可以參考下
    2021-05-05
  • 6個(gè)必備的Java并發(fā)面試種子題目合集

    6個(gè)必備的Java并發(fā)面試種子題目合集

    并發(fā)是Java面試的經(jīng)常會(huì)考到的知識(shí)點(diǎn),這篇文章主要為大家整理了6個(gè)必備的Java并發(fā)面試種子題目,文中的示例代碼簡(jiǎn)潔易懂,需要的可以學(xué)習(xí)一下
    2023-07-07

最新評(píng)論

乡宁县| 林西县| 富宁县| 修文县| 高密市| 揭东县| 天长市| 墨竹工卡县| 阳曲县| 安仁县| 黄陵县| 平原县| 垣曲县| 西峡县| 昌黎县| 泰兴市| 磐安县| 阳东县| 安多县| 清苑县| 特克斯县| 廊坊市| 威海市| 林甸县| 南阳市| 内黄县| 松潘县| 湟源县| 大连市| 宁国市| 平塘县| 清丰县| 潜江市| 临洮县| 合山市| 瑞金市| 郓城县| 铁岭县| 神农架林区| 合川市| 张家口市|