我的 github 部落格
之前我們學習了記憶體模型和執行緒,了解了併發程式設計的目的是為了讓程式執行得更快,提高程式的響應速度,雖然我們希望通過多執行緒執行任務讓程式執行得更快,但是同時也會面臨非常多的挑戰,比如像執行緒安全問題、執行緒上下文切換的問題、硬體和軟體資源限制等問題,這些都是併發程式設計給我們帶來的難題。jmm
和執行緒,初步**了jvm
怎麼實現併發,而本篇文章,我們的關注點是jvm
如何實現高效
其中執行緒安全問題是我們最關心的問題之一,我們接下來主要就圍繞著執行緒安全的問題來展開。
2.1.1 定義
當多個執行緒訪問乙個物件時,如果不用考慮這些執行緒在執行時環境下的排程和交替執行,也不需要進行額外的同步,或者在呼叫方進行任何其他的協調操作,呼叫這個物件的行為都可以獲得正確的結果,那這個物件是執行緒安全的
要求執行緒安全的**都必須具備乙個特徵:2.1.2 分類**本身封裝了所有必要的正確性保障手段(如互斥同步等),令呼叫者無須關心多執行緒的問題,更無須自己採取任何措施來保證多執行緒的正確呼叫。
下面將按照執行緒安全的程度由強至弱分成五類
例子:2.1.3 實現thread
類的suspend()
和resume()
,乙個嘗試中斷執行緒,乙個嘗試恢復執行緒,在併發條件下,有可能會造成死鎖
可分成兩大手段:1.互斥同步 b.使用重入鎖本篇重點在虛擬機器本身
reentrantlock
:
之前在 高階之路 | 奇妙的 thread 之旅中也提到過重入鎖的使用,相信看過的讀者還有一些印象
2.非阻塞同步3.無同步方案a.可重入**/純**b.執行緒本地儲存2.2.1 適應性自旋
注意:自旋等待不能代替阻塞,它雖然能避免執行緒切換的開銷,但會占用處理器時間,因此自旋等待的時間必須要有一定的限度,如果自旋超過了限定的次數(預設2.2.2 鎖消除10
次)仍未成功獲鎖,就需要掛執行緒了2.2.3 鎖粗化
2.2.4 輕量級鎖
首先先理解2.之後虛擬機會嘗試用hotspot
虛擬機器的物件頭的記憶體布局:分為兩部分cas
操作將物件的mark word
更新為指向lock record
的指標。若更新動作成功,那麼當前執行緒就擁有了該物件的鎖,且物件mark word
的鎖標誌位變為00
,即處於輕量級鎖定狀態;反之,虛擬機會先檢查物件的mark word
是否指向當前執行緒的棧幀,若是,則當前執行緒已有該物件的鎖,可直接進入同步塊繼續執行,否則說明改物件已被其他執行緒搶占。如下圖:另外,如果有兩條以上的執行緒爭用同乙個鎖,那輕量級鎖就不再有效,要膨脹為重量級鎖,鎖標誌位變為10
,mark word
中儲存的就是指向重量級鎖的指標,後面等待鎖的執行緒也要進入阻塞狀態q:處於輕量級鎖狀態時,會不會使用自旋鎖這個競爭機制2.2.5 偏向鎖a:執行緒首先會通過
cas
獲取鎖,失敗後通過自旋鎖來嘗試獲取鎖,再失敗鎖就膨脹為重量級鎖。所以輕量級鎖狀態下可能會有自旋鎖的參與(cas
將物件頭的標記指向鎖記錄指標失敗的時候)能夠寫出高效能、高伸縮性的併發程式是一門藝術,而了解併發在底層是如何實現的,則是掌握這門藝術的前提,也是成長為高階程式設計師的必備知識!如果文章對您有一點幫助的話,希望您能點一下贊,您的點讚,是我前進的動力加油吧!騷年!以夢為馬,不負韶華!
一夜搞懂 JVM 位元組碼執行引擎
我的 github 部落格 編譯的結果從本地機器碼轉變為位元組碼,是儲存格式發展的一小步,卻是程式語言發展的一大步 首先,丟擲靈魂三問 如果你對上述問題理解得還不是特別透徹的話,可以看下這篇文章 如果理解了,你可以關閉網頁,開啟遊戲放鬆了hhh 下面,筆者將帶你 jvm核心的組成部分之一 執行引擎。...
JVM執行緒安全與鎖優化
1.不可變 不可變的物件一定是執行緒安全的。如string類。2.絕對執行緒安全 3.相對執行緒安全 4.執行緒相容 5.執行緒對立 1.互斥同步 阻塞式同步 1 同步指的是 多個執行緒併發訪問共享資料時,保證共享資料在同一時刻只能被乙個執行緒使用。2 互斥指的是 同步的手段。如 臨界區 互斥量和訊...
JVM學習 (九)執行緒安全和鎖優化
從以前流行的面向過程程式設計到現在的物件導向程式設計,物件導向程式設計極大的提公升了現代軟體開發的效率和規模,但是不可避免的是物件之間的相互切換,為了讓程式維護的更好更好,我們必須引入 高效併發 來保證併發的正確性 安全性和效率性。比較寬泛的定義 沒有什麼可以操作性 如果乙個物件可以被多個執行緒同時...