免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
鎖的內(nèi)存語義

鎖的內(nèi)存語義

鎖的釋放-獲取建立的happens-before關系

鎖是Java并發(fā)編程中最重要的同步機制.鎖除了讓臨界區(qū)互斥執(zhí)行外,還可以讓釋放鎖的線程向獲取同一個鎖的線程發(fā)送信息.


假設線程A執(zhí)行writer()方法,隨后線程B執(zhí)行reader()方法.根據(jù)happens-before規(guī)則,這個過程happens-before關系可以分為3類.

  • 根據(jù)程序次序規(guī)則,1 happens-before 2,2 happens-before 3;4 happens-before 5,5 happensbefore 6。
  • 根據(jù)監(jiān)視器鎖規(guī)則,3 happens-before 4
  • 根據(jù)happens-before的傳遞性,2 happens-before 5

上述happens-before關系的圖形化表示形式如下圖所示

每一個箭頭鏈接的兩個節(jié)點,代表了一個happens-before關系。黑色箭頭表示程序順序規(guī)則;橙色箭頭表示監(jiān)視器鎖規(guī)則;藍色箭頭表示組合這些規(guī)則后提供的happens-before保證。

上圖中在線程A釋放了鎖之后,隨后線程B獲取同一個鎖。在上圖職工2 happens-before 5,因此,線程A在釋放鎖之前所有可見的共享變量,在線程B獲取同一個鎖之后,將立刻變得對線程B可見。


鎖的釋放和獲取的內(nèi)存語義

當線程釋放鎖時,JMM會把該線程對應的本地內(nèi)存的共享變量刷新到主內(nèi)存.以上面的MonitorExample程序為例,A線程釋放鎖后,共享數(shù)據(jù)的狀態(tài)示意圖如圖下圖所示。

當線程獲取鎖時,JMM會把該線程所對應的本地內(nèi)存置為無效.從而使得被監(jiān)視器保護的臨界代碼必須從主內(nèi)存中讀取共享變量.


對比鎖釋放-獲取內(nèi)存語義與volatile寫-讀的內(nèi)存語義可以看出:鎖釋放與volatile寫有相同的內(nèi)存語義;鎖獲取與volatile讀有相同的內(nèi)存語義。

對鎖釋放和鎖獲取的內(nèi)存語義小結(jié)

  • 線程A釋放一個鎖,實質(zhì)上是對線程A向接下來要獲取這個鎖的某個線程發(fā)出了(線程A對共享變量所做修改的)消息
  • 線程B獲取一個鎖,實質(zhì)上是線程B接收之前某個線程發(fā)出的(在釋放這個鎖之前對共享變量所做修改的)消息
  • 線程A釋放鎖,隨后線程B獲取這個鎖,這個過程實質(zhì)上是線程A通過主內(nèi)存向線程B發(fā)送消息(共享變量).

鎖內(nèi)存語義的實現(xiàn)

示例代碼


ReentrantLock的實現(xiàn)依賴于Java同步器框架AbstractQueuedSynchronizer(AQS)。AQS使用一個整型的volatile變量(命名為state)來維護同步狀態(tài)

ReentrantLock分為公平鎖和非公平鎖

公平鎖

使用公平鎖時,加鎖方法lock()調(diào)用軌跡如下。
1)ReentrantLock:lock()。
2)FairSync:lock()。
3)AbstractQueuedSynchronizer:acquire(int arg)。
4)ReentrantLock:tryAcquire(int acquires)。
在第4步真正開始加鎖,下面是該方法的源代碼。


從上面源代碼中我們可以看出,加鎖方法首先讀volatile變量state。
在使用公平鎖時,解鎖方法unlock()調(diào)用軌跡如下.
1)ReentrantLock:unlock()。
2)AbstractQueuedSynchronizer:release(int arg)。
3)Sync:tryRelease(int releases)。
在第3步真正開始釋放鎖,下面是該方法的源代碼。

從上面的源代碼可以看出,在釋放鎖的最后寫volatile變量state.

公平鎖在釋放鎖的最后寫volatile變量state,在獲取鎖時首先讀這個volatile變量.根據(jù)volatile變量的happens-before規(guī)則,釋放鎖的線程寫在volatile變量之前可見的共享變量,在獲取鎖的線程讀取同一個volatile變量后立即變得對獲取鎖的線程可見.

非公平鎖

非公平鎖的釋放和公平鎖完全一樣,所以這里僅僅分析非公平鎖的獲取。使用非公平鎖時,加鎖方法lock()調(diào)用軌跡如下。
1)ReentrantLock:lock()。
2)NonfairSync:lock()。
3)AbstractQueuedSynchronizer:compareAndSetState(int expect,int update)。
在第3步真正開始加鎖,下面是該方法的源代碼。


該方法以原子操作的方式更新state變量,把Java的compareAndSet()方法調(diào)用簡稱為CAS。JDK文檔對該方法的說明如下:如果當前狀態(tài)值等于預期值,則以原子方式將同步狀態(tài)設置為給定的更新值。此操作具有volatile讀和寫的內(nèi)存語義。

編譯器不會對volatile讀與volatile讀后面的任意內(nèi)存操作重排序;編譯器不會對volatile寫與volatile寫前面的任意內(nèi)存操作重排序。組合這兩個條件,意味著為了同時實現(xiàn)volatile讀和volatile寫的內(nèi)存語義,編譯器不能對CAS與CAS前面和后面的任意內(nèi)存操作重排序.

公平鎖和非公平鎖的內(nèi)存語義小結(jié)
·公平鎖和非公平鎖釋放時,最后都要寫一個volatile變量state。
·公平鎖獲取時,首先會去讀volatile變量。
·非公平鎖獲取時,首先會用CAS更新volatile變量,這個操作同時具有volatile讀和volatile寫的內(nèi)存語義。

鎖釋放-獲取的內(nèi)存語義的實現(xiàn)至少有下面兩種方式

  • 利用volatile變量的寫-讀所具有的內(nèi)存語義。
  • 利用CAS所附帶的volatile讀和volatile寫的內(nèi)存語義。

concurrent包的實現(xiàn)

由于Java的CAS同時具有volatile讀和volatile寫的內(nèi)存語義,因此Java線程之間的通信現(xiàn)在有了下面4種方式。

  • A線程寫volatile變量,隨后B線程讀這個volatile變量
  • A線程寫volatile變量,隨后B線程用CAS更新這個volatile變量
  • A線程用CAS更新一個volatile變量,隨后B線程用CAS更新這個volatile變量
  • A線程用CAS更新一個volatile變量,隨后B線程讀這個volatile變量

Java的CAS會使用現(xiàn)代處理器上提供的高效機器級別的原子指令,這些原子指令以原子方式對內(nèi)存執(zhí)行讀-改-寫操作,這是在多處理器中實現(xiàn)同步的關鍵(從本質(zhì)上來說,能夠支持原子性讀-改-寫指令的計算機,是順序計算圖靈機的異步等價機器,因此任何現(xiàn)代的多處理器都會去支持某種能對內(nèi)存執(zhí)行原子性讀-改-寫操作的原子指令)。同時,volatile變量的讀/寫和CAS可以實現(xiàn)線程之間的通信。把這些特性整合在一起,就形成了整個concurrent包得以實現(xiàn)的基石。如果我們仔細分析concurrent包的源代碼實現(xiàn),會發(fā)現(xiàn)一個通用化的實現(xiàn)模式。

  • 聲明共享變量為volatile變量
  • 使用CAS的院子條件更新來實現(xiàn)線程之間的同步,同時配合volatile的讀/寫和CAS所具有的volatile讀和寫的內(nèi)存語義來實現(xiàn)線程之間的通信.

AQS,非阻塞數(shù)據(jù)結(jié)構(gòu)和原子變量類(java.util.concurrent.atomic包中的類),這些concurrent包中的基礎類都是使用這種模式來實現(xiàn)的,而concurrent包中的高層類又是依賴于這些基礎類來實現(xiàn)的

參考書籍:<>

來源:https://www.icode9.com/content-3-439001.html
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
深入理解Java內(nèi)存模型(五)——鎖
讀書筆記之Java并發(fā)原理與JMM
【Java線程】Java內(nèi)存模型總結(jié)
深入理解Java內(nèi)存模型(四):volatile
深入分析volatile的實現(xiàn)原理
【JAVA并發(fā)第四篇】線程安全
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服