摘要:所以大家看下面的圖,就是線程跑過來加鎖的一個過程。好線程現在就重新嘗試加鎖,這時還是用操作將從變為,此時就會成功,成功之后代表加鎖成功,就會將設置為。此外,還要把加鎖線程設置為線程自己,同時線程自己就從等待隊列中出隊了。
ReentrantLock和AQS的關系 ReentrantLock使用
AbstractQueuedSynchronizer,抽象隊列同步器;給大家畫一個圖先,看一下ReentrantLock和AQS之間的關系。
AbstractQueuedSynchronizer為ReentrantLock的靜態內部類
2、默認為非公平鎖
3、最終會調用AbstractQueuedSynchronizer子類NonfairSync.lock()方法;
lock()方法做了什么事呢?
首先需要知道AQS會維護兩個變量state(初始值0)、exclusiveOwnerThread(初始值null),源碼如下,記錄線程狀態與當前加鎖線程
線程1跑過來調用ReentrantLock的lock()方法嘗試進行加鎖,這個加鎖的過程,直接就是用CAS操作將state值從0變為1。
如果之前沒人加過鎖,那么state的值肯定是0,此時線程1就可以加鎖成功。
一旦線程1加鎖成功了之后,就可以設置當前加鎖線程是自己。所以大家看下面的圖,就是線程1跑過來加鎖的一個過程。
state記錄加鎖次數,為0時釋放鎖
鎖的互斥是如何實現的?線程2跑過來一下看到,哎呀!state的值不是0啊?所以CAS操作將state從0變為1的過程會失敗,因為state的值當前為1,說明已經有人加鎖了!
接著線程2會看一下,是不是自己之前加的鎖啊?當然不是了,“加鎖線程”這個變量明確記錄了是線程1占用了這個鎖,所以線程2此時就是加鎖失敗。
接著,線程2會將自己放入AQS中的一個等待隊列,因為自己嘗試加鎖失敗了,此時就要將自己放入隊列中來等待,等待線程1釋放鎖之后,自己就可以重新嘗試加鎖了
所以大家可以看到,AQS是如此的核心!AQS內部還有一個等待隊列,專門放那些加鎖失敗的線程!
同樣,給大家來一張圖,一起感受一下:
源碼
線程2進來加鎖失敗后,會進入等待隊列;等待隊列為鏈表
接著,線程1在執行完自己的業務邏輯代碼之后,就會釋放鎖!他釋放鎖的過程非常的簡單,就是將AQS內的state變量的值遞減1,如果state值為0,則徹底釋放鎖,會將“加鎖線程”變量也設置為null!
整個過程,參見下圖:
LockSupport.unpark(s.thread);
接下來,會從等待隊列的隊頭喚醒線程2重新嘗試加鎖。
好!線程2現在就重新嘗試加鎖,這時還是用CAS操作將state從0變為1,此時就會成功,成功之后代表加鎖成功,就會將state設置為1。
此外,還要把“加鎖線程”設置為線程2自己,同時線程2自己就從等待隊列中出隊了。
最后再來一張圖,大家來看看這個過程。
參考資料https://juejin.im/post/5c07e5...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/72655.html
摘要:概述前面已經講解了關于的非公平鎖模式,關于非公平鎖,內部其實告訴我們誰先爭搶到鎖誰就先獲得資源,下面就來分析一下公平鎖內部是如何實現公平的如果沒有看過非公平鎖的先去了解下非公平鎖,因為這篇文章前面不會講太多內部結構,直接會對源碼進行分析前文 概述 前面已經講解了關于AQS的非公平鎖模式,關于NonfairSync非公平鎖,內部其實告訴我們誰先爭搶到鎖誰就先獲得資源,下面就來分析一下公平...
摘要:內部提供了兩種的實現,一種公平模式,一種是非公平模式,如果沒有特別指定在構造器中,默認是非公平的模式,我們可以看一下無參的構造函數。 概述 并發編程中,ReentrantLock的使用是比較多的,包括之前講的LinkedBlockingQueue和ArrayBlockQueue的內部都是使用的ReentrantLock,談到它又不能的不說AQS,AQS的全稱是AbstractQueue...
摘要:的主要功能和關鍵字一致,均是用于多線程的同步。而僅支持通過查詢當前線程是否持有鎖。由于和使用的是同一把可重入鎖,所以線程可以進入方法,并再次獲得鎖,而不會被阻塞住。公平與非公平公平與非公平指的是線程獲取鎖的方式。 1.簡介 可重入鎖ReentrantLock自 JDK 1.5 被引入,功能上與synchronized關鍵字類似。所謂的可重入是指,線程可對同一把鎖進行重復加鎖,而不會被阻...
摘要:公平策略在多個線程爭用鎖的情況下,公平策略傾向于將訪問權授予等待時間最長的線程。使用方式的典型調用方式如下二類原理的源碼非常簡單,它通過內部類實現了框架,接口的實現僅僅是對的的簡單封裝,參見原理多線程進階七鎖框架獨占功能剖析 showImg(https://segmentfault.com/img/remote/1460000016012582); 本文首發于一世流云的專欄:https...
摘要:作者畢來生微信鎖狀態轉換分類以后幫助我們提供了線程同步機制,通過顯示定義同步鎖來實現對象之間的同步。等待重新嘗試因為在中是用關鍵字聲明的,故可以在線程間可見再次判斷一下能否持有鎖可能線程同步代碼執行得比較快,已經釋放了鎖,不可以就返回。 作者 : 畢來生微信: 878799579 鎖狀態轉換 showImg(https://segmentfault.com/img/remote/...
閱讀 3528·2021-09-22 15:50
閱讀 3233·2019-08-30 15:54
閱讀 2748·2019-08-30 14:12
閱讀 3058·2019-08-30 11:22
閱讀 2079·2019-08-29 11:16
閱讀 3574·2019-08-26 13:43
閱讀 1192·2019-08-23 18:33
閱讀 920·2019-08-23 18:32