理解高併發(5).synchronized原理及用法

歷史最優久的使用最方便的線程同步的關鍵字。必須點贊
一、synchronized 特性
  • 同一時刻只有一個線程訪問臨界資源
  • 其它未獲取到鎖執行權的線程必須排隊等待
  • 保證共享資源的原子性、可見性和有序性
  • 進入synchronized範圍內自動加鎖,synchronized作用域外鎖自動消除,即使異常也會釋放鎖
  • 簡單方便(不需要人工釋放鎖)
  • jdk1.6後性能做了很大優化

二、synchronized用法
  • 普通方法同步
作用: 所有訪問該對象實例該方法的線程,必須排隊執行
如: synchronized public void add(){
}
  • 靜態方法同步
作用: 所有采用類名.方法名訪問的線程, 必須排隊執行
如: synchronized public static void add(){
}
  • 代碼塊同步
作用: 所有訪問到該表達式的線程,必須排隊執行
synchronized(表達式){
}
        表達式可以是:
        a. this                 表示該對象,僅適用於非靜態方法的情況
        b. 類名.class        適用於靜態方法和非靜態方法
c. 對象實例           適用於靜態方法和非靜態方法
d. 成員變量         適用於靜態方法和非靜態方法

三、 synchronized原理
synchronized的底層實現原理都是通過對象頭裏面的monitor(監視器鎖)來實現的。每個對象頭裏面都有一個指針指向monitor,monitor中又包含有訪問計數器,能否進入是根據計數器值來判斷的。

  • 同步代碼塊原理
同步代碼塊是通過monitorenter、monitorexit來控制。 字節碼指令如下, 操作原理:
1、當訪問到monitorenter時, 當前線程會嘗試獲取該對象的monitor所有權
獲取所有權的依據是monitor的計數器值是否爲0, 爲0則獲取到了,同時將計數器值 +1
2、如果已獲取到monitor所有權, 則直接將計數器 +1並進入運行指令階段
3、如果沒有嘗試獲取該對象的monitor持有權,會進入等待隊列進行阻塞
  • 同步方法原理
同步方法是通過方法常量池中的方法表關鍵字來控制, 如果用synchronized修改方法,那麼常量池裏面會有ACC_SYNCHRONIZEDR進行修飾。
當線程訪問加了synchronized的方法時, 會去判斷是否有ACC_SYNCHRONIZED標識,
1、如果有該標識, 當前線程會嘗試獲取該對象的monitor所有權
獲取所有權的依據是monitor的計數器值是否爲0, 爲0則獲取到了,同時將計數器值 +1
2、如果已獲取到monitor所有權, 則直接將計數器 +1並進入運行指令階段
3、如果沒有嘗試獲取該對象的monitor持有權,會進入等待隊列進行阻塞

四、synchronized可重入性
可重入性也是依據是否可獲取monitor持有權來判斷。
發佈了83 篇原創文章 · 獲贊 9 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章