從以前流行的面向過程程式設計到現在的物件導向程式設計,物件導向程式設計極大的提公升了現代軟體開發的效率和規模,但是不可避免的是物件之間的相互切換,為了讓程式維護的更好更好,我們必須引入「高效併發」來保證併發的正確性、安全性和效率性。
比較寬泛的定義(沒有什麼可以操作性):如果乙個物件可以被多個執行緒同時使用,那麼它就是執行緒安全的。
比較嚴謹並且有操作性的定義:當多個執行緒同時訪問同乙個物件時,如果不用考慮這些執行緒在執行時環境下的排程和交替執行,也需要進行額外的同步操作,或者在呼叫方法進行任何其他的協調操作,呼叫這個物件的行為都可以獲得正確的結果,那麼就稱這個物件是執行緒安全的。
3.無同步方案
要保證執行緒安全並非一定需要進行阻塞或者阻塞同步,同步與執行緒安全之間並沒有必要的聯絡。如果保證乙個方法本來就不涉及共享資料,那麼自然不需要任何同步措施來保證其確定性。因此有些**天生就是安全的,例如:
1️⃣可重入**。又被稱為純**,指的是**執行的任何階段中斷它轉而執行其他的**,而在控制權返回後也不會對結果產生什麼影響。所有的可重入**都是執行緒安全的,但是並不是所有執行緒安全的**都是可重入的。比較簡單的判定規則:如果乙個方法的返回結果是可以**的,只要輸入相同的資料,就能返回相同的結果,那麼它就滿足可重入的要求。
2️⃣執行緒本地儲存。如果乙個執行緒中的資料必須和其他**共享,那麼就看看這些共享資料的**是否能保證在同乙個執行緒中執行。如果能夠保證,就可以把共享資料的可見性放在乙個執行緒中,這樣就可以保證是執行緒安全的。
jdk5到jdk6有乙個重要的改進項,就是對鎖進行了很多優化,這些技術都是為了提高程式的執行速度。
很多時候鎖定狀態維持的時間很短,如果為了這段時間去掛起或者恢復執行緒十分不值得。可以通過讓等待的鎖執行乙個忙迴圈(自旋)而不是將其阻塞,這就是自旋鎖。
jdk6中加入自適應的自旋鎖,意味著自旋的時間不是固定的,虛擬機會根據運**況來設定自旋次數的閾值。
指的是虛擬機器即時編譯器在執行時,對一些**要求同步,但是對被檢測到不可能存在共享資料競爭的鎖進行消除。主要判斷依據是逃逸分析的資料支援。
原則上是要求同步塊越小越好,但是一系列對於同一物件反覆的加鎖解鎖的過程中,頻繁的進行互斥同步操作會導致不必要的效能損耗。因此可以考慮將鎖粗化。
jdk6後加入的新型鎖機制,「輕量級」是相對於使用作業系統互斥量的傳統鎖而言的。但是輕量級鎖並不能代替重量級鎖,設計的初衷是在沒有多執行緒競爭的前提下,減少傳統的重量級鎖使用作業系統互斥量的效能消耗。
hotspot虛擬機器中物件頭分為兩部分,第一部分儲存物件自身的執行時資料,例如雜湊碼、gc分代年齡等。這部分是實現輕量級鎖和偏向鎖的關鍵。另一部分用來儲存指向方法區物件型別的指標。在32位的虛擬機器中物件在沒有被鎖定的情況下,2個位元用來儲存鎖標誌位,還有1個位元固定為0,除了未被鎖定的情況,還有輕量級鎖定、重量級鎖定、gc標記等。
工作過程:**即將進入同步塊的時候,如果這個同步物件沒有被鎖定(01狀態),虛擬機器首先將在當前執行緒的棧幀中建立乙個名為鎖記錄的空間,用來儲存鎖物件目前的markword的拷貝,然後虛擬機器將cas操作嘗試把物件的markword更新為lockrecord的指標,如果成功了就代表著執行緒擁有這個物件的鎖,並且物件鎖標誌位轉變為「00」,表示此物件處於輕量級鎖定。如果更新操作失敗了,就意味著至少存在一條執行緒和當前執行緒競爭取得該物件的鎖。這時候比對物件的markword是否指向當前執行緒的棧幀,如果是那麼執行緒已經擁有這個物件的鎖;否則說明了這個鎖已經被其他執行緒所占用了。
需要注意的是如果兩個執行緒以上爭同乙個鎖,輕量級鎖就不再有效,必須膨脹為重量級鎖。
解鎖過程也是一樣,通過cas操作,如果物件的markword仍然指向執行緒的鎖記錄,就把物件當前的markword和執行緒複製的displacedmark替換回來。
輕量級鎖能夠提公升同步效能的依據是「對於絕大部分的鎖,在整個同步週期中都是不存在競爭的」,如果不存在競爭,輕量級鎖通過cas操作成功避免了互斥量的開銷,但是如果存在競爭,反而會比重量級鎖更慢。
目的是消除資料在無競爭情況下的同步原語,進一步提高程式的執行效能。它的意思是這個鎖會偏向於第乙個獲得它的過程,如果在接下來的執行過程中,該鎖一直沒有被其他的執行緒獲取,則持有偏向鎖的執行緒將永遠不需要同步。
JVM學習(九) 鎖優化
1 高效併發是jdk1.5到jdk1.6的乙個重要改進,出現了適應性自旋 adaptive spinning 鎖消除 lock elimination 鎖粗化 lock coarsening 輕量級鎖 lightweight locking 和偏向鎖 biased locking 等一系列鎖優化技術...
JVM執行緒安全與鎖優化
1.不可變 不可變的物件一定是執行緒安全的。如string類。2.絕對執行緒安全 3.相對執行緒安全 4.執行緒相容 5.執行緒對立 1.互斥同步 阻塞式同步 1 同步指的是 多個執行緒併發訪問共享資料時,保證共享資料在同一時刻只能被乙個執行緒使用。2 互斥指的是 同步的手段。如 臨界區 互斥量和訊...
要點提煉 理解JVM之執行緒安全 鎖優化
本篇將介紹執行緒安全所涉及的概念和分類 同步實現的方式及虛擬機器的底層運作原理,以及虛擬機器為了實現高效併發所採取的一系列鎖優化措施。1.概述 在要點提煉 理解jvm之記憶體模型 執行緒中主要介紹了虛擬機器如何實現 併發 現在的關注點是虛擬機器如何實現 高效 2.執行緒安全 在實現高效之前,首先需要...