標籤:線程 log 加鎖 最小 更新 原理 java線程 之間 工作
可見度:一個線程對共用變數值的修改,能夠及時唄其他線程看到。
共用變數:如果一個變數在多個線程的記憶體中都存在副本,那麼這個變數就是這幾個線程的共用變數。
java記憶體模型(JMM)
描述了java程式中各種變數(線程共用變數)的訪問規則,以及在JVM中將變數儲存到記憶體和記憶體中讀取出變數這樣的底層細節。
1)所有的變數儲存在主記憶體中
2)每個線程都有自己獨立的工作記憶體,裡面儲存該線程中使用到的變數的副本(主記憶體中該變數的一份拷貝)。
兩條規定
1)線程對共用變數的所有操作都必須在自己的工作記憶體中進行,不能直接從主記憶體中讀寫
2)不同線程之間無法之間訪問其他線程工作記憶體中的變數,線程間變數值的傳遞需要通過主記憶體來完成。
共用變數可見度實現的原理
線程1對共用變數的修改要想唄線程2及時看到,必須經過如下2個步驟:
1)把工作記憶體1中更新過的記憶體變數重新整理到主記憶體中。
2)把主記憶體中最小的共用變數的值更新到工作記憶體2中。
可見度的實現方式Java語言層面支援的可見度實現方式:
1)synchronized
2)volatile
synchronized實現可見度
synchronized能夠實現:
1)原子性(同步)
2)可見度
JMM關於synchronized的兩條規定:
1)線程解鎖前,必須把共用變數的最新值重新整理到主記憶體中。
2)線程加鎖時,將清空工作記憶體中共用變數的值,從而使用共用變數時需要從主記憶體中重新讀取最小的值(注意:加上和解鎖需要是同一把鎖)
線程執行互斥代碼的過程:
1)獲得互斥鎖
2)清空工作記憶體
3)從主記憶體拷貝變數的最新副本到工作記憶體
4)執行代碼
5)將更改後的共用變數的值重新整理到主記憶體
6)釋放互斥鎖。
重排序
重排序:代碼書寫的順序與實際執行的順序不同,指令重排序是編譯器或處理器為了提高線程效能而作的最佳化。
1)編譯器最佳化的重排序(編譯器最佳化)
2)指令級並行重排序(處理器最佳化)
3)記憶體系統的重排序(處理器最佳化)
as-if-serial
as-if-serial:無論如何重排序,程式執行的結果應該與代碼順序執行的結果一致(java編譯器,運行時和處理器都會保證java在單線程下遵循as-if-serial語義)。
java線程-java多線程之可見度