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

Java利用AQS實(shí)現(xiàn)自定義鎖

 更新時間:2022年07月25日 15:34:38   作者:#小蘇打  
本文主要介紹了Java利用AQS實(shí)現(xiàn)自定義鎖,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

什么是AQS

AQS(AbstractQueuedSynchronizer),中文名抽象隊列同步器

AQS定義了一套多線程訪問共享資源的同步器框架,主要用來自定義鎖和同步器

AQS原理

AQS 核心思想:

  • 如果被請求的共享資源空閑,則將當(dāng)前請求資源的線程設(shè)置為有效的工作線程,并且將共享資源設(shè)置為鎖定狀態(tài)。
  • 如果被請求的共享資源被占用,將暫時獲取不到鎖的線程加入到阻塞隊列中,等待被喚醒和鎖的分配

實(shí)現(xiàn)核心思想的的隊列:CLH隊列

CLH隊列是一個虛擬的雙向隊列,AQS 是將每條請求共享資源的線程封裝成一個 CLH 鎖隊列的一個結(jié)點(diǎn)(Node)來實(shí)現(xiàn)鎖的分配。

共享資源用 volatile 關(guān)鍵詞修飾,保證線程間的可見性

   /**
     * The synchronization state.
     */
    private volatile int state;

0狀態(tài)表示空閑,1狀態(tài)或以上表示不空閑

共享資源(state)的訪問方式有三種:  

  1. getState()   獲得共享資源狀態(tài)
  2. setState()   設(shè)置共享資源狀態(tài)
  3. compareAndSetState() 更改共享資源狀態(tài)(底層unsafe類)

 源代碼如下

    /**
     * Returns the current value of synchronization state.
     * This operation has memory semantics of a {@code volatile} read.
     * @return current state value
     */
    protected final int getState() {
        return state;
    }
 
    /**
     * Sets the value of synchronization state.
     * This operation has memory semantics of a {@code volatile} write.
     * @param newState the new state value
     */
    protected final void setState(int newState) {
        state = newState;
    }
    /**
     * Atomically sets synchronization state to the given updated
     * value if the current state value equals the expected value.
     * This operation has memory semantics of a {@code volatile} read
     * and write.
     *
     * @param expect the expected value
     * @param update the new value
     * @return {@code true} if successful. False return indicates that the actual
     *         value was not equal to the expected value.
     */
    protected final boolean compareAndSetState(int expect, int update) {
        // See below for intrinsics setup to support this
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }

利用AQS實(shí)現(xiàn)自定義鎖

一:首先創(chuàng)建一個類實(shí)現(xiàn)Lock接口,它有6個方法需要實(shí)現(xiàn)

  • lock():加鎖(不成功進(jìn)入阻塞隊列等待)
  • lockInterruptibly():是否加鎖可打斷
  • tryLock()://加鎖(不成功不會進(jìn)入阻塞隊列等待,可以去做其他事情)
  • tryLock(long time,TimeUnit unit):加鎖(規(guī)定時間內(nèi)未獲得則放棄加鎖)
  • unlock():釋放鎖
  • newCondition():創(chuàng)建條件變量

二:創(chuàng)建一個內(nèi)部類,繼承AbstractQueuedSynchronizer

可以根據(jù)需求重寫具體方法,總共有5種方法

  • isHeldExclusively():該線程是否正在獨(dú)占資源。只有用到condition才需要去實(shí)現(xiàn)它。
  • tryAcquire(int):獨(dú)占方式。嘗試獲取資源,成功則返回true,失敗則返回false。
  • tryRelease(int):獨(dú)占方式。嘗試釋放資源,成功則返回true,失敗則返回false。
  • tryAcquireShared(int):共享方式。嘗試獲取資源。負(fù)數(shù)表示失??;0表示成功,但沒有剩余可用資源;正數(shù)表示成功,且有剩余資源。
  • tryReleaseShared(int):共享方式。嘗試釋放資源,如果釋放后允許喚醒后續(xù)等待結(jié)點(diǎn)返回true,否則返回false。

三:我需要自定義一個獨(dú)占鎖,不可重入,具有變量條件的鎖

分析

  • 獨(dú)占鎖:AQS同步器中需要重寫?yīng)氄挤绞降墨@取資源tryAcquire(int)和釋放資源tryRelease(int)方法
  • 不可重入:AQS同步器需要實(shí)現(xiàn)isHeldExclusively():
  • 具有條件變量:AQS同步器中 return new ConditionObject();

具體代碼如下

//自定義鎖(不可重入)(獨(dú)占鎖)(條件變量)
class MyLock implements Lock{
    //內(nèi)部類,AQS同步器類
    class MySync extends AbstractQueuedSynchronizer{
        @Override
        protected boolean tryAcquire(int arg) {
            if (compareAndSetState(0,1)){
                System.out.println("獲得鎖成功");
                //加上了鎖,并設(shè)置owner為當(dāng)前線程
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            System.out.println("獲得鎖失敗");
            return false;
        }
 
        @Override
        protected boolean tryRelease(int arg) {
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }
 
        @Override
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }
 
        public Condition newCondition(){
            return new ConditionObject();
        }
    }
 
    private MySync mySync = new MySync();
 
    @Override //加鎖(不成功進(jìn)入阻塞隊列等待)
    public void lock() {
        mySync.acquire(1);
    }
 
    @Override //加鎖可打斷
    public void lockInterruptibly() throws InterruptedException {
        mySync.acquireInterruptibly(1);
    }
 
    @Override //加鎖(不成功不會進(jìn)入阻塞隊列等待,可以去做其他事情)
    public boolean tryLock() {
        return mySync.tryAcquire(1);
    }
 
    @Override //嘗試加鎖 帶時間
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return mySync.tryAcquireNanos(1,unit.toNanos(time));
    }
 
    @Override //釋放鎖
    public void unlock() {
        mySync.release(1);
    }
 
    @Override //創(chuàng)建條件變量
    public Condition newCondition() {
        return mySync.newCondition();
    }
}

到此這篇關(guān)于Java利用AQS實(shí)現(xiàn)自定義鎖的文章就介紹到這了,更多相關(guān)Java AQS實(shí)現(xiàn)自定義鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java線程狀態(tài)變換過程代碼解析

    Java線程狀態(tài)變換過程代碼解析

    這篇文章主要介紹了Java線程狀態(tài)變換過程代碼解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-06-06
  • 深入理解Spring AOP

    深入理解Spring AOP

    這篇文章主要介紹了深入理解Spring AOP,詳細(xì)的介紹了spring aop的具體實(shí)現(xiàn)與理論
    2017-01-01
  • Java Swing JList列表框的實(shí)現(xiàn)

    Java Swing JList列表框的實(shí)現(xiàn)

    這篇文章主要介紹了Java Swing JList列表框的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • IntelliJ IDEA編譯項目報錯

    IntelliJ IDEA編譯項目報錯 "xxx包不存在" 或 "找不到符號"

    這篇文章主要介紹了IntelliJ IDEA編譯項目報錯 "xxx包不存在" 或 "找不到符號" ,文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • java程序設(shè)計語言的優(yōu)勢及特點(diǎn)

    java程序設(shè)計語言的優(yōu)勢及特點(diǎn)

    在本篇文章里小編給大家分享的是一篇關(guān)于java程序設(shè)計語言的優(yōu)勢及特點(diǎn)的內(nèi)容,需要的朋友們可以學(xué)習(xí)參考下。
    2020-02-02
  • Java中本地緩存的4種實(shí)現(xiàn)方式總結(jié)

    Java中本地緩存的4種實(shí)現(xiàn)方式總結(jié)

    這篇文章主要介紹了Java中本地緩存的4種實(shí)現(xiàn)方式,分別是基礎(chǔ)緩存實(shí)現(xiàn)、GuavaLoadingCache、SpringBoot整合Caffeine和JetCache,通過實(shí)例代碼,詳細(xì)講解了每種緩存技術(shù)的特點(diǎn)和使用方法,需要的朋友可以參考下
    2025-04-04
  • Log4j按級別輸出日志到不同文件的實(shí)現(xiàn)方法

    Log4j按級別輸出日志到不同文件的實(shí)現(xiàn)方法

    下面小編就為大家?guī)硪黄狶og4j按級別輸出日志到不同文件的實(shí)現(xiàn)方法。
    2016-11-11
  • 通過代碼示例了解submit與execute的區(qū)別

    通過代碼示例了解submit與execute的區(qū)別

    這篇文章主要介紹了通過代碼示例了解submit與execute的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • springboot如何使用redis的incr創(chuàng)建分布式自增id

    springboot如何使用redis的incr創(chuàng)建分布式自增id

    這篇文章主要介紹了springboot如何使用redis的incr創(chuàng)建分布式自增id,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 解決異常FileNotFoundException:class path resource找不到資源文件的問題

    解決異常FileNotFoundException:class path resource找不到資源文件的問題

    今天小編就為大家分享一篇關(guān)于解決異常FileNotFoundException:class path resource找不到資源文件的問題,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12

最新評論

山丹县| 堆龙德庆县| 土默特左旗| 仪征市| 冕宁县| 徐州市| 开鲁县| 铜鼓县| 高雄市| 西盟| 惠安县| 乌兰察布市| 西平县| 自贡市| 广东省| 溧水县| 彰武县| 渝中区| 峨边| 黑龙江省| 永济市| 靖州| 宁海县| 浏阳市| 于都县| 儋州市| 乌鲁木齐市| 英山县| 定襄县| 新竹县| 枣庄市| 育儿| 漠河县| 三原县| 舞钢市| 渑池县| 达日县| 泗水县| 博白县| 苏尼特右旗| 石棉县|