19 Java記憶體模型與線程_JVM層面的鎖優化

来源:https://www.cnblogs.com/knowledgeispower/archive/2022/12/16/16988221.html
-Advertisement-
Play Games

1 鎖優化歷史 synchronized 從 JDK1.0到JDK1.5 ,效率低 JDK1.5到JDK1.6,JVM團隊對synchronized進行深度優化,加入了:適應性自旋、鎖消除、鎖膨脹、輕量級鎖、偏向鎖 等優化技術 JDK1.5 開始,加入java.util.concurrent,提供A ...


目錄

1 鎖優化歷史

  1. synchronized 從 JDK1.0到JDK1.5 ,效率低
  2. JDK1.5到JDK1.6,JVM團隊對synchronized進行深度優化,加入了:適應性自旋、鎖消除、鎖膨脹、輕量級鎖、偏向鎖 等優化技術
  3. JDK1.5 開始,加入java.util.concurrent,提供API層面的輕量級鎖應用

為什麼優化synchronized?

互斥同步對性能最大的影響是阻塞的實現,掛起線程和恢複線程的操作都需要轉入內核態中完成,這些操作給Java虛擬機的併發性能帶來了很大的壓力。

2 自旋鎖與自適應自旋

2.1 關於自旋鎖

自旋鎖歷史進程:首次出現在JDK1.4.2,但預設關閉(使用-XX:+UseSpinning參數開啟),在JDK6開始預設開啟。

自旋鎖實現邏輯:如果鎖被其它線程占有,那麼本線程不放棄處理器的執行時間,並執行一個忙迴圈(自旋),直至得到鎖。

自旋鎖弊端:如果鎖被占用的時間很長,那麼自旋的線程只會白白消耗處理器資源,帶來性能的浪費

自旋鎖優化:

  1. 引入自旋次數:如果自旋超過了限定的次數仍然沒有成功獲得鎖,就應當使用傳統的方式去掛起線程。自旋次數的預設值是10次,可以啟用參數-XX:PreBlockSpin來更改。(次數在JDK1.4.2已經實現)
  2. 引入了自適應自旋

2.1 自旋鎖優化:自適應自旋

原來:所有線程的自旋時間統一的(PreBlockSpin配置值 * 單次自旋時間)
自適應自旋:自旋的時間不固定,JVM根據前一次在同一個鎖上的自旋時間及鎖的擁有者的狀態來決定。
自適應自旋情形:

例如1:線程A、B,鎖L。A先通過自旋獲取鎖,那麼JVM認為B也能通過自旋獲取到鎖,隨即給B分配自旋時間,並且這個時間也是綜合之前的自旋時間
例如2:鎖L,線程A B C 通過自旋,都沒有獲取到鎖,那麼JVM會對後續的線程省略自旋過程,以免浪費處理器資源

3 鎖消除

定義:指虛擬機即時編譯器在運行時,對一些代碼要求同步,但是對被檢測到不可能存在共用數據競爭的鎖進行消除

判斷依據:源於逃逸分析的數據支持,如果判斷到一段代碼中,在堆上的所有數據都不會逃逸出去被其他線程訪問到,那就可以把它們當作棧上數據對待,認為它們是線程私有的,同步加鎖自然就無須再進行。

舉例:

一段看起來沒有同步的代碼:

public String concatString(String s1, String s2, String s3) 
{ 
    return s1 + s2 + s3;
}

javac編譯後,會變為以下同等代碼:

public String concatString(String s1, String s2, String s3) { 
    StringBuffer sb = new StringBuffer();
    sb.append(s1); 
    sb.append(s2);
    sb.append(s3); 
    return sb.toString();
}
//append()方法有synchronize修飾

分析:
jvm觀察變數sb,經過逃逸分析後會發現它的動態作用域被限制在concatString()方法內部。可以採用無鎖操作。
在解釋執行時這裡仍然會加鎖,但在即時編譯之後,這段代碼就會忽略所有的同步措施而直接執行。

鎖消除總結:

JVM會進行逃逸分析,符合條件的,在編譯為機器碼時,會消除所有同步措施

4 鎖粗化

定義:假如一串零碎的操作都對同一個對象加鎖,JVM會把加鎖同步的範圍擴展(粗化)到整個操作序列的外部

舉例:
例如上面concatString()方法,將鎖擴展到第一個append()操作之前最後一個append()操作之後,這樣只需加鎖一次

5 輕量級鎖

邏輯:無競爭的情況下使用CAS操作去消除同步使用的互斥量
輕量級鎖提升性能的依據:“對於絕大部分的鎖,在整個同步周期內都是不存在競爭的”這一經驗法則
過程分析:後續補充

6 偏向鎖

邏輯:在無競爭的情況下把整個同步都消除掉,連CAS操作都不去做
“偏”的理解:鎖會偏向於第一個獲得它的線程,如果在接下來的執行過程中,該鎖一直沒有被其他的線程獲取,則持有偏向鎖的線程將永遠不需要再進行同步。

過程分析:後續補充


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 介紹 可曾想過我們每次創建新項目,或者換地方寫程式,都要把之前寫過的工具類找出來又要複製粘貼一遍有些麻煩,尤其是寫uni-app自定義模板主要還是開發工具完成的。這時為什麼不自己做一款自己的uni-app工具箱,每次用直接從商城導入就行了 ...
  • 在學習 jsp 的過程中,使用 IDEA 軟體新建 web 文件,右擊新建 jsp 時,沒有找到 jsp 文件。可能是沒有添加 web 路徑,該如何解決呢? ...
  • 作者:倪新明 ADR是一種性價比非常高的架構決策文檔化實踐,團隊引入和實踐成本很低,卻能為團隊帶來極大收益! 1 團隊研發麵臨的問題 不論是在傳統的IT行業,還是互聯網行業,研發團隊在架構決策層面或多或少的都會面臨以下問題或挑戰: •新成員加入團隊,對系統現有的架構決策可能會盲目遵守,只知其然,不知 ...
  • 1、設計想法 原理與之前的串口發送模塊一樣,1位的數據位和8位的數據位再加上1位的停止位。唯一不同的是在接收的時候要考慮到有干擾的情況下,為了避免干擾,我們對每位數據進行多次採樣,按出現概率大的值為該數據位的值。 如果按照通常想法在每bits位中間取值的話,bit3位出現圖中的干擾很有可能會讀出錯誤 ...
  • 家居網購項目實現02 5.功能04-會員登錄 5.1需求分析/圖解 需求如圖: 輸入用戶名、密碼後提交 判斷該用戶是否存在 如果存在,顯示登錄成功頁面 否則返回登錄頁面,要求重新登錄 要求改進登錄密碼為md5加密 5.2思路分析 5.3代碼實現 根據上述分析圖,在對應的層添加方法 5.3.1dao層 ...
  • unique_ptr的成員函數在上一篇博客中幾乎全部涵蓋,其實還有一個很有踢掉,即std::unique_ptr::get_deleter字面已經很明顯了,就獲得deleter 智能指針採通過引用計數我們能解決多次釋放同一塊記憶體空間的問題,並且和之間直接移交管理權的方式比較這種方式更加靈活安全。 但 ...
  • 怎麼引入不同的庫? 線上安裝庫 1)pip install 模塊名 2)國內源: 清華:https://pypi.tuna.tsinghua.edu.cn/simple 阿裡雲:http://mirrors.aliyun.com/pypi/simple/ 中國科技大學 https://pypi.mi ...
  • 1.函數 #函數語法: #函數名規範:小謝字母開頭,不同字母下劃線隔開(字母數字下劃線) #def 函數名(): #函數體:希望函數做的事情 1.1.無參函數 #無參函數 def music(): print("唱著又沒動聽的歌聲...") #調用函數 music() 1.2.有參函數 #有參函數 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...