摘要:并發機制與底層實現原理是輕量級的它在多處理器開發中保證了共享變量的可見性,因為它不會引起線程上下文的切換和調度,所以比的使用和執行成本更底。如果線程間存在鎖競爭,會帶來額外的鎖撤銷的消耗。輕量級鎖競爭的線程不會阻塞,提高了程序的響應速度。
java并發機制與底層實現原理 volatile
volatile是輕量級的synchronize,它在多處理器開發中保證了共享變量的“可見性”,因為它不會引起線程上下文的切換和調度,所以比synchronize的使用和執行成本更底。
為了提高處理速度,處理器不直接和內存進行通信,而是先將系統內存的數據讀到內部緩存(L1,L2或其他)后再進行操作,但操作完不知道何時會寫到內存。使用volatile變量,在操作后,JVM會發出lock指令
將當前處理器緩存行的數據寫回到系統內存
這個寫回內存的操作會使在其他cpu里緩存了該內存地址的數據無效
synchronize 同步基礎synchronize實現同步的基礎,具體表現為三種形式
對于普通同步方法,鎖是當前實例對象
對于靜態同步方法,鎖是當前類的class對象
對于同步方法塊,鎖是Synchronize括號里配置的對象
當一個線程試圖訪問同步代碼塊時,它首先必須得到鎖,退出或拋出異常時必須釋放鎖。那么鎖到底存在那里,鎖里會存儲什么信息。
java對象頭synchonize用的鎖是存在java對象頭里的。如果對象是數組類型,則JVM用三個字寬存儲對象頭,如果對象為非數組類型,則用二個字寬存儲對象頭。32位中,一字寬等于四字節(32bit)
長度 | 內容 | 說明 |
32/64bit | Mark Word | 存儲對象的hashCode或鎖信息等。 |
32/64bit | Class Metadata Address | 存儲到對象類型數據的指針 |
32/64bit | Array length | 數組的長度(如果當前對象是數組) |
在運行期間Mark Word里存存儲的數據會隨著鎖標志位的變化而變化。會成為下面的一種
為了減少獲得鎖與釋放鎖所帶來的性能消耗,引入“偏向鎖”和“輕量級鎖".所以在java中存在四種狀態
無鎖狀態
偏向鎖狀態
輕量級鎖狀態
自旋鎖
重量級鎖狀態
它會隨著競爭情況逐漸升級。鎖可以升級但不能降級,意味著偏向鎖升級成輕量級鎖后不能降級成偏向鎖
偏向鎖Hotspot的作者經過以往的研究發現大多數情況下鎖不僅不存在多線程競爭,而且總是由同一線程多次獲得,為了讓線程獲得鎖的代價更低而引入了偏向鎖。當一個線程訪問同步塊并獲取鎖時,會在對象頭和棧幀中的鎖記錄里存儲鎖偏向的線程ID,以后該線程在進入和退出同步塊時不需要花費CAS操作來加鎖和解鎖。
流程圖中展示偏向鎖的獲取釋放以及升級至輕量鎖
1.輕量級鎖加鎖:
線程在執行同步塊之前,JVM會先在當前線程的棧楨中創建用于存儲鎖記錄的空間,并將對象頭中的Mark Word復制到鎖記錄中,官方稱為Displaced Mark Word。然后線程嘗試使用CAS將對象頭中的Mark Word替換為指向鎖記錄的指針。如果成功,當前線程獲得鎖,如果失敗,表示其他線程競爭鎖,當前線程便嘗試使用自旋來獲取鎖。
2.輕量級鎖解鎖
輕量級解鎖時,會使用原子的CAS操作來將Displaced Mark Word替換回到對象頭,如果成功,則表示沒有競爭發生。如果失敗,表示當前鎖存在競爭,鎖就會膨脹成重量級鎖。下圖是兩個線程同時爭奪鎖,導致鎖膨脹的流程圖。
借用網上流程圖如下:
當竟爭存在時,如果線程可以很快獲得鎖,那么可以不在OS層掛起線程(線程切換平均消耗8K個時鐘周期),讓線程多做幾個空操作(自旋)
如果同步塊過長,自旋失敗,會降低系統性能
如果同步塊很短,自旋成功,節省線程掛起切換時間,擔升系統性能
鎖對比鎖 | 優點 | 缺點 | 適用場景 |
偏向鎖 | 加鎖和解鎖不需要額外的消耗,和執行非同步方法比僅存在納秒級的差距。 | 如果線程間存在鎖競爭,會帶來額外的鎖撤銷的消耗。 | 適用于只有一個線程訪問同步塊場景。 |
輕量級鎖 | 競爭的線程不會阻塞,提高了程序的響應速度。 | 如果始終得不到鎖競爭的線程使用自旋會消耗CPU | 追求響應時間。同步塊執行速度非常快。 |
重量級鎖 | 線程競爭不使用自旋,不會消耗CPU。 | 線程阻塞,響應時間緩慢。 | 追求吞吐量。同步塊執行速度較長。 |
偏向鎖,輕量級鎖,自旋鎖不是JAVA語言層上的優化方法
內置于JVM中的獲取鎖的優化方法與獲取鎖的步驟
偏向鎖可用可先嘗試偏向鎖
輕量級鎖可用可先嘗試輕量級鎖
1與2都失敗,則嘗試自旋鎖
再失敗,嘗試普通鎖,使用OS互斥量在操作系統層掛起
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68805.html
摘要:基礎問題的的性能及原理之區別詳解備忘筆記深入理解流水線抽象關鍵字修飾符知識點總結必看篇中的關鍵字解析回調機制解讀抽象類與三大特征時間和時間戳的相互轉換為什么要使用內部類對象鎖和類鎖的區別,,優缺點及比較提高篇八詳解內部類單例模式和 Java基礎問題 String的+的性能及原理 java之yield(),sleep(),wait()區別詳解-備忘筆記 深入理解Java Stream流水...
摘要:基礎問題的的性能及原理之區別詳解備忘筆記深入理解流水線抽象關鍵字修飾符知識點總結必看篇中的關鍵字解析回調機制解讀抽象類與三大特征時間和時間戳的相互轉換為什么要使用內部類對象鎖和類鎖的區別,,優缺點及比較提高篇八詳解內部類單例模式和 Java基礎問題 String的+的性能及原理 java之yield(),sleep(),wait()區別詳解-備忘筆記 深入理解Java Stream流水...
摘要:基礎問題的的性能及原理之區別詳解備忘筆記深入理解流水線抽象關鍵字修飾符知識點總結必看篇中的關鍵字解析回調機制解讀抽象類與三大特征時間和時間戳的相互轉換為什么要使用內部類對象鎖和類鎖的區別,,優缺點及比較提高篇八詳解內部類單例模式和 Java基礎問題 String的+的性能及原理 java之yield(),sleep(),wait()區別詳解-備忘筆記 深入理解Java Stream流水...
摘要:為程序員金三銀四精心挑選的余道面試題與答案,歡迎大家向我推薦你在面試過程中遇到的問題我會把大家推薦的問題添加到下面的常用面試題清單中供大家參考。 為Java程序員金三銀四精心挑選的300余道Java面試題與答案,歡迎大家向我推薦你在面試過程中遇到的問題,我會把大家推薦的問題添加到下面的常用面試題清單中供大家參考。 前兩天寫的以下博客,大家比較認可,熱度不錯,希望可以幫到準備或者正在參加...
閱讀 2679·2023-04-25 20:28
閱讀 1849·2021-11-22 09:34
閱讀 3687·2021-09-26 10:20
閱讀 1834·2021-09-22 16:05
閱讀 3085·2021-09-09 09:32
閱讀 2502·2021-08-31 09:40
閱讀 2099·2019-08-30 13:56
閱讀 3320·2019-08-29 17:01