要點提煉 理解JVM之執行緒安全 鎖優化

2021-08-21 13:36:42 字數 2848 閱讀 5526

本篇將介紹執行緒安全所涉及的概念和分類、同步實現的方式及虛擬機器的底層運作原理,以及虛擬機器為了實現高效併發所採取的一系列鎖優化措施。

1.概述

在要點提煉| 理解jvm之記憶體模型&執行緒中主要介紹了虛擬機器如何實現『併發』,現在的關注點是虛擬機器如何實現『高效』。

2.執行緒安全

在實現高效之前,首先需要保證併發的正確性,因此本節先介紹執行緒安全。

a.定義:當多個執行緒訪問乙個物件時,如果不用考慮這些執行緒在執行時環境下的排程和交替執行,也不需要進行額外的同步,或者在呼叫方進行任何其他的協調操作,呼叫這個物件的行為都可以獲得正確的結果,那這個物件是執行緒安全的。

要求執行緒安全的**都必須具備乙個特徵

**本身封裝了所有必要的正確性保障手段(如互斥同步等),令呼叫者無須關心多執行緒的問題,更無須自己採取任何措施來保證多執行緒的正確呼叫。

b.分類:按照執行緒安全的程度由強至弱分成五類

絕對執行緒安全:完全滿足之前給出的執行緒安全的定義,即達到「不管執行時環境如何,呼叫者都不需要任何額外的同步措施」。

相對執行緒安全:能保證對該物件單獨的操作是執行緒安全的,在呼叫時無需做額外保障措施,但對於一些特定順序的連續呼叫,可能需要在呼叫端使用額外的同步措施來保證呼叫的正確性。

執行緒相容:物件本身非執行緒安全的,但可以通過在呼叫端正確地使用同步手段來保證物件在併發環境中可以安全地使用,

執行緒對立:無論呼叫端是否採取了同步措施,都無法在多執行緒環境中併發使用的**。

c.執行緒安全的實現

可分成兩大手段,本篇重點在虛擬機器本身

互斥同步(mutual exclusion&synchronization)

互斥是因,同步是果;互斥是方法,同步是目的。

使用重入鎖reentrantlock

選擇:在synchronized能實現需求的情況下,優先考慮使用它來進行同步。下兩張圖是兩者在不同處理器上的吞吐量對比。

非阻塞同步(non-blocking synchronization):

無同步方案

滿足可重入性的**一定是執行緒安全的,反之,滿足執行緒安全的**不一定是可重入的。

3.鎖優化a.適應性自旋(adaptive spinning)

自適應自旋鎖:自旋的時間不再固定,而是由該鎖上的上次自旋時間及鎖的擁有者的狀態共同決定。具體表現是:

b.鎖消除(lock elimination)

c.鎖粗化(lock coarsening)

一般情況下,會將同步塊的作用範圍限制到只在共享資料的實際作用域中才進行同步,使得需要同步的運算元量盡可能變小,保證就算存在鎖競爭,等待鎖的執行緒也能盡快拿到鎖。

但如果反覆操作對同乙個物件進行加鎖和解鎖,即使沒有執行緒競爭,頻繁地進行互斥同步操作也會導致不必要的效能損耗,此時,虛擬機器將會把加鎖同步的範圍粗化到整個操作序列的外部,這樣只需加一次鎖。

d.輕量級鎖(lightweight locking)

首先先理解hotspot虛擬機器的物件頭的記憶體布局:分為兩部分

之後虛擬機會嘗試用cas操作將物件的mark word更新為指向lock record的指標。若更新動作成功,那麼當前執行緒就擁有了該物件的鎖,且物件mark word的鎖標誌位變為00,即處於輕量級鎖定狀態;反之,虛擬機會先檢查物件的mark word是否指向當前執行緒的棧幀,若當前執行緒已有該物件的鎖,可直接進入同步塊繼續執行,否則說明改物件已被其他執行緒搶占。如下圖。

另外,如果有兩條以上的執行緒爭用同乙個鎖,那輕量級鎖就不再有效,要膨脹為重量級鎖,鎖標誌位變為10,mark word中儲存的就是指向重量級鎖的指標,後面等待鎖的執行緒也要進入阻塞狀態。

e.偏向鎖(biased locking)

JVM執行緒安全與鎖優化

1.不可變 不可變的物件一定是執行緒安全的。如string類。2.絕對執行緒安全 3.相對執行緒安全 4.執行緒相容 5.執行緒對立 1.互斥同步 阻塞式同步 1 同步指的是 多個執行緒併發訪問共享資料時,保證共享資料在同一時刻只能被乙個執行緒使用。2 互斥指的是 同步的手段。如 臨界區 互斥量和訊...

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

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

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

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