Java并發(fā)機(jī)制的底層實(shí)現(xiàn)原理

volatile的應(yīng)用

  • valatile實(shí)現(xiàn)原則
    • Lock前綴指令會引起處理器緩存回寫到內(nèi)存
    • 一個處理器的緩存回寫到內(nèi)存會導(dǎo)致其他處理器的緩存無效
  • volatile的使用優(yōu)化
    • 追加字節(jié)64字節(jié)的方式來優(yōu)化性能(Java 7下可能不生效,采用了其他追加字節(jié)的方式)

synchronized的實(shí)現(xiàn)原理與應(yīng)用

相信絕大數(shù)人在腦海里對synchronized的第一印象就是重量級鎖,性能消耗特別高,不到萬不得一最好不要使用synchronized,當(dāng)然了,在1.6版本之前確實(shí)是這樣的,但是在1.6版本對synchronized進(jìn)行了優(yōu)化,其中最主要的就是引入了偏向鎖、輕量級鎖。后續(xù)會有所提及。

  • 對于普通同步方法,鎖是當(dāng)前實(shí)例對象
  • 對于靜態(tài)同步方法,鎖是當(dāng)前類的Class對象
  • 對于同步方法塊,鎖是synchronized括號里配置的對象

記住synchronized是通過JVM實(shí)現(xiàn)的,如果修飾的同步塊,與之對應(yīng)的命令monitorentermonitorexit。如果是同步方法,則是依靠方法修飾符上的ACC_SYNCHRONIZED

  • Java對象頭

Java對象頭的存儲結(jié)構(gòu)(32位JVM)

鎖狀態(tài) 25bit 4bit 1bit(偏向鎖) 2bit(鎖標(biāo)志位)
無鎖狀態(tài) 對象的hashCode 對象分代年齡 0 01

Java對象頭的存儲結(jié)構(gòu)(64位JVM)
不支持HTML標(biāo)簽,只能截圖了


image.png
  • 鎖級別(由低到高)

無鎖狀態(tài)->偏向鎖狀態(tài)->輕量級鎖狀態(tài)->重量級鎖狀態(tài)(只能升級不能降級)

偏向鎖

初次獲取鎖的時候,將自身的ThreadID寫入到mark word的ThreadId字段內(nèi),并且將偏向鎖的狀態(tài)置為1。如果再有線程來獲取鎖的時候,直接比較ThreadID是否一致。

輕量級鎖

兩個線程競爭,其中只會有一個競爭成功,另外一個進(jìn)行自旋CAS。

鎖的優(yōu)缺點(diǎn)對比及適用場景

優(yōu)點(diǎn) 缺點(diǎn) 適用場景
偏向鎖 加鎖和解鎖不需要額外的消耗,和執(zhí)行非同步方法相比僅存在納秒級的差距 如果線程間存在鎖競爭,會帶來額外的鎖撤銷的消耗 使用只有一個線程訪問同步塊場景
輕量級鎖 競爭的線程不會阻塞,提高了程序的響應(yīng)速度 如果始終得不到鎖競爭的線程,使用自旋會消耗CPU 追求響應(yīng)時間,同步塊執(zhí)行速度非???/td>
重量級鎖 線程競爭不適用自旋,不會消耗CPU 線程阻塞,響應(yīng)時間緩慢 追求吞吐量,同步塊執(zhí)行速度較長

原子操作的實(shí)現(xiàn)原理

  • 如何實(shí)現(xiàn)原子性

    • 使用總線鎖保證原子性(使用處理器提供的Lock #信號,當(dāng)一個處理器在總線上輸出此信號時,其他處理器的請求將被阻塞住,所以開銷比較大)
    • 使用緩存鎖保證原子性(修改內(nèi)部的內(nèi)存地址,通過緩存一致性機(jī)制來保證操作的原子性,因為緩存一致性機(jī)制會阻止同時修改由兩個以上處理器緩存的內(nèi)存區(qū)域數(shù)據(jù),當(dāng)其他處理器回寫已被鎖定的緩存行的數(shù)據(jù)時,會使緩存行無效)
      • 有兩種特殊情況處理器不會使用緩存鎖定
        • 當(dāng)操作的數(shù)據(jù)不能被緩存在處理器內(nèi)部或操作的數(shù)據(jù)跨多個緩存行時,則會調(diào)用總線鎖定
        • 有些處理器不支持緩存鎖定。(Intel 486和Pentium處理器)
  • Java如何實(shí)現(xiàn)原子操作

    • 實(shí)現(xiàn)方式
      • 自旋CAS
    • 鎖機(jī)制實(shí)現(xiàn)原子操作
      JVM內(nèi)部多種鎖機(jī)制:偏向鎖、輕量級鎖、互斥鎖。除了偏向鎖,其它都用到了CAS
    • CAS實(shí)現(xiàn)原理及存在的問題
      • JVM中的CAS操作是利用處理器提供的CMPXCHG指令實(shí)現(xiàn)的
      • CAS實(shí)現(xiàn)原子操作的三大問題
        1. ABA問題(1.5版本提供的AtomicStampedReference來解決的)
        2. 循環(huán)時間長,開銷大(如果處理器支持pause命令,效率有所提升。第一,延遲流水線執(zhí)行命令,使CPU不會消耗過多的執(zhí)行資源。第二,避免循環(huán)推出的時候因內(nèi)存順序沖突而引起CPU流水線被清空,從而提高CPU的執(zhí)行效率)
        3. 只能保證一個共享變量的原子操作(1.5版本提供的AtomicReference類來保證引用對象之間的原子性,就可以把多個變量放在一個對象里來進(jìn)行CAS操作)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容