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

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

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

什么是AQS

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

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

AQS原理

AQS 核心思想:

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

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

CLH隊(duì)列是一個(gè)虛擬的雙向隊(duì)列,AQS 是將每條請求共享資源的線程封裝成一個(gè) CLH 鎖隊(duì)列的一個(gè)結(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)建一個(gè)類實(shí)現(xiàn)Lock接口,它有6個(gè)方法需要實(shí)現(xiàn)

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

二:創(chuàng)建一個(gè)內(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。

三:我需要自定義一個(gè)獨(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)入阻塞隊(duì)列等待)
    public void lock() {
        mySync.acquire(1);
    }
 
    @Override //加鎖可打斷
    public void lockInterruptibly() throws InterruptedException {
        mySync.acquireInterruptibly(1);
    }
 
    @Override //加鎖(不成功不會進(jìn)入阻塞隊(duì)列等待,可以去做其他事情)
    public boolean tryLock() {
        return mySync.tryAcquire(1);
    }
 
    @Override //嘗試加鎖 帶時(shí)間
    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í)價(jià)值,需要的朋友可以參考下
    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í)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • IntelliJ IDEA編譯項(xiàng)目報(bào)錯(cuò)

    IntelliJ IDEA編譯項(xiàng)目報(bào)錯(cuò) "xxx包不存在" 或 "找不到符號"

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

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

    在本篇文章里小編給大家分享的是一篇關(guān)于java程序設(shè)計(jì)語言的優(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í)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • springboot如何使用redis的incr創(chuàng)建分布式自增id

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

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

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

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

最新評論

永修县| 晋宁县| 衡东县| 资兴市| 广州市| 来宾市| 泸州市| 济南市| 维西| 晋州市| 锡林郭勒盟| 巨野县| 和顺县| 红河县| 旌德县| 沁水县| 滨州市| 息烽县| 黄骅市| 长寿区| 麻栗坡县| 金堂县| 临湘市| 马关县| 彰化县| 赤城县| 乌鲁木齐县| 旬阳县| 云阳县| 姜堰市| 辽宁省| 麟游县| 西贡区| 昆山市| 四子王旗| 安义县| 沂南县| 鞍山市| 锡林浩特市| 平度市| 晴隆县|