欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

什么是AQS

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

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

AQS原理

AQS 核心思想:

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

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

CLH隊(duì)列是一個(gè)虛擬的雙向隊(duì)列,AQS 是將每條請(qǐng)求共享資源的線程封裝成一個(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()://加鎖(不成功不會(huì)進(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 //加鎖(不成功不會(huì)進(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java精品項(xiàng)目瑞吉外賣之新增菜品與分頁查詢篇

    Java精品項(xiàng)目瑞吉外賣之新增菜品與分頁查詢篇

    這篇文章主要為大家詳細(xì)介紹了java精品項(xiàng)目-瑞吉外賣訂餐系統(tǒng),此項(xiàng)目過大,分為多章獨(dú)立講解,本篇內(nèi)容為新增菜品和分頁查詢功能的實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • java實(shí)現(xiàn)二維碼生成的幾個(gè)方法(推薦)

    java實(shí)現(xiàn)二維碼生成的幾個(gè)方法(推薦)

    本篇文章主要介紹了java實(shí)現(xiàn)二維碼生成的幾個(gè)方法(推薦),具有一定的參考價(jià)值,有興趣的可以了解一下。
    2016-12-12
  • SpringSecurity整合JWT的使用示例

    SpringSecurity整合JWT的使用示例

    本文主要介紹了SpringSecurity整合JWT的使用示例,整合Spring?Security和JWT,可以使我們的應(yīng)用程序更加安全和高效,感興趣的可以了解一下
    2023-11-11
  • java?線程池如何執(zhí)行策略又拒絕哪些策略

    java?線程池如何執(zhí)行策略又拒絕哪些策略

    這篇文章主要介紹了java?線程池如何執(zhí)行策略又拒絕哪些策略,文章通過線程池的執(zhí)行方法?execute()?展開全篇內(nèi)容,需要的小伙伴可以參考一下
    2022-05-05
  • Java并發(fā)Map面試線程安全數(shù)據(jù)結(jié)構(gòu)全面分析

    Java并發(fā)Map面試線程安全數(shù)據(jù)結(jié)構(gòu)全面分析

    本文將探討如何在Java中有效地應(yīng)對(duì)這些挑戰(zhàn),介紹一種強(qiáng)大的工具并發(fā)Map,它能夠幫助您管理多線程環(huán)境下的共享數(shù)據(jù),確保數(shù)據(jù)的一致性和高性能,深入了解Java中的并發(fā)Map實(shí)現(xiàn),包括ConcurrentHashMap和ConcurrentSkipListMap,及相關(guān)知識(shí)點(diǎn)
    2023-09-09
  • JDBC連接MySQL并實(shí)現(xiàn)模糊查詢

    JDBC連接MySQL并實(shí)現(xiàn)模糊查詢

    本文詳細(xì)講解了JDBC連接MySQL并實(shí)現(xiàn)模糊查詢的方式,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-01-01
  • 如何用Spring發(fā)送電子郵件

    如何用Spring發(fā)送電子郵件

    這篇文章主要介紹了如何用Spring發(fā)送電子郵件,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2021-02-02
  • 關(guān)于spring版本與JDK版本不兼容的問題及解決方法

    關(guān)于spring版本與JDK版本不兼容的問題及解決方法

    這篇文章主要介紹了關(guān)于spring版本與JDK版本不兼容的問題,本文給大家?guī)砹私鉀Q方法,需要的朋友可以參考下
    2018-11-11
  • SpringBoot實(shí)現(xiàn)獲取客戶端IP地理位置

    SpringBoot實(shí)現(xiàn)獲取客戶端IP地理位置

    在當(dāng)今互聯(lián)的世界中,了解客戶端的地理位置對(duì)于提供個(gè)性化服務(wù)和增強(qiáng)用戶體驗(yàn)至關(guān)重要,使用本文為大家介紹了SpringBoot獲取客戶端IP地理位置的相關(guān)方法,需要的小伙伴可以參考下
    2023-11-11
  • 使用spring@value加載時(shí)機(jī)

    使用spring@value加載時(shí)機(jī)

    這篇文章主要介紹了使用spring@value加載時(shí)機(jī)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03

最新評(píng)論