JVM執行緒安全與鎖優化

2021-08-07 07:27:33 字數 2818 閱讀 6036

1.        不可變:

不可變的物件一定是執行緒安全的。如string類。

2.        絕對執行緒安全

3.        相對執行緒安全

4.        執行緒相容

5.        執行緒對立

1.        互斥同步(阻塞式同步)

1)        同步指的是:多個執行緒併發訪問共享資料時,保證共享資料在同一時刻只能被乙個執行緒使用。

2)        互斥指的是:同步的手段。如:臨界區、互斥量和訊號量。

3)        最基本的同步互斥手段:synchronized關鍵字。

a)        原理:synchronized關鍵字經過編譯後,會在同步**塊前後分別形成monitorenter和monitorexit這兩個位元組碼指令。

b)        在執行monitorenter指令時,首先要嘗試獲取物件鎖。若這個物件沒被設定鎖,或已經擁有了這個物件鎖,把鎖的計數器+1。

c)        相應的執行monitorexit指令時,鎖計數器-1,當為0時釋放鎖。

d)        若獲得物件失敗則阻塞當前執行緒。

4)        另一種手段:reentrantlock來實現

reentrantlock增加的新功能:

a)        等待中斷:當持有鎖的執行緒長期不釋放鎖的時候,正在等待的執行緒可以選擇放棄等待。

b)        公平鎖:可以講多個執行緒在等待同乙個鎖時,必須按照申請鎖的時間順序依次獲得鎖。

c)        鎖繫結多個條件:乙個reentranlock物件可以同時繫結多個condition物件。

5)        兩種方式的比較:

a)        在jdk1.6之前在多執行緒環境中synchronized的吞吐量下降的嚴重,但reentranlock效能幾乎不變。

b)        在jdk1.6之後二者效能基本上持平。

c)        應該優先考慮使用synchronized來同步。

2.        非阻塞同步

1)        互斥同步屬於一種悲觀的併發策略。即總認為不去做同步措施就一定會出現問題,故無論共享資料是否真的會出現競爭,都要加鎖。

2)        非執行緒阻塞:是基於衝突檢測的樂觀併發控制策略。即先操作,如果沒有其它執行緒徵用共享資料,則成功。如果共享資料有徵用,採取補償措施。(不斷的重試,直到成功)

3.        無同步方案

如果方法中不涉及共享資料,那它自然無須任何同步措施去保證正確性。

1)        可重入**

可重入的**都是執行緒安全的,但並非所有的執行緒安全的**都是可重入的。

2)        執行緒本地儲存

鎖優化技術:適應性自旋、鎖消除、鎖粗化、輕量級鎖和偏向鎖。

1.        自旋鎖:當兩個或兩個以上的執行緒同時並行執行,讓後面請求鎖的那個執行緒「稍等一下」,但不放棄處理器的執行時間,看看持有所的執行緒是否能很快釋放鎖。

2.        缺點:自旋的執行緒只會白白消耗處理器資源,帶來效能上的浪費。故需要使等待時間有一定的限度

3.        改進:等待時間要自適應。等待時間隨著程式執行和效能監控資訊的不斷完善。

1.        鎖消除:虛擬機器及時編譯器在執行時,對一些**上要求同步,但是被檢測到不可能存在共享資料競爭的鎖進行消除。

2.        判斷依據:源於逃逸分析的資料支援。若堆上的所有資料都不會逃逸出去從而被其他執行緒訪問到,那就可以吧它們當作棧上的資料看待。

1.        上面出現的問題:如果一系列的連續操作都對同乙個物件反覆加鎖和解鎖,甚至加鎖操作是出現在迴圈體中,那即使沒有執行緒競爭,頻繁地進行互斥同步操作也會導致不必要的效能損耗。

2.        措施:如果虛擬機器探測到有這樣一串零碎的操作都對同乙個物件加鎖,【將會把加鎖同步的範圍擴充套件到整個操作序列外部】。

1.        加鎖過程:

1)        **進入到同步**塊的時候,如果此同步物件沒有被鎖定,將會在當前執行緒的棧幀中建立乙個名為鎖記錄(lock record)空間,用來儲存物件目前的頭資料。

2)        將物件的頭記錄更新為指向lock record的指標。

a)        更新成功:那麼這個執行緒就擁有了該物件的鎖

b)        失敗:檢查物件的物件頭是否指向當前執行緒的棧幀。

a)        是:說明當前執行緒已經擁有這個物件的鎖,直接進入同步塊中執行。

b)        否:說明這個鎖物件已經被其他執行緒搶占。

3)        如果兩條以上執行緒徵用同乙個鎖,那輕量級鎖失效。

2.        解鎖過程:

1)        若物件的物件頭仍然指向現成的鎖記錄,則把物件當前的mark word和執行緒中副本替換回來。

a)        成功:整個同步過程完成

b)        失敗:說明其他執行緒嘗試獲取該鎖,那就要釋放鎖的同時喚醒被掛起的執行緒。

1.        與輕量級鎖的區別:

輕量級鎖:是在無競爭情況下,消除同步使用的互斥量。

偏向鎖:在無競爭情況下把整個同步都消除掉。

2.        加鎖過程:

1)        當鎖物件第一次被執行緒獲取的時候,虛擬機器包物件頭中的標記為設為「01」。

2)        把獲取到這個鎖的執行緒的id記錄在物件的mark word之中。

3.        解鎖過程:

1)        當有另外乙個執行緒去嘗試獲取這個鎖時,偏向模式宣告結束。

2)        根據鎖物件目前是否處於被鎖定的狀態,撤銷偏向後恢復到「01」或「00」。

4.        優點:

提高帶有同步但競爭的程式效能。

一夜搞懂 JVM 執行緒安全與鎖優化

我的 github 部落格 之前我們學習了記憶體模型和執行緒,了解了jmm和執行緒,初步 了jvm怎麼實現併發,而本篇文章,我們的關注點是jvm如何實現高效 併發程式設計的目的是為了讓程式執行得更快,提高程式的響應速度,雖然我們希望通過多執行緒執行任務讓程式執行得更快,但是同時也會面臨非常多的挑戰,...

JVM學習 (九)執行緒安全和鎖優化

從以前流行的面向過程程式設計到現在的物件導向程式設計,物件導向程式設計極大的提公升了現代軟體開發的效率和規模,但是不可避免的是物件之間的相互切換,為了讓程式維護的更好更好,我們必須引入 高效併發 來保證併發的正確性 安全性和效率性。比較寬泛的定義 沒有什麼可以操作性 如果乙個物件可以被多個執行緒同時...

執行緒安全與鎖優化

樂觀鎖 cas aba 版本號 atomicstampedreference 時間戳atomicmarkablereference boolean 可重入 絕對執行緒安全,不依賴共享資料 使用引數,區域性變數 自旋鎖 認為鎖很快釋放,占用cpu迴圈獲取鎖,超過一定次數 時間 再掛起執行緒,自旋次數上...