深入理解synchronized:從使用到原理的進階指南

目錄

一、核心機制深度解析

1. 對象頭(Object Header)與Mark Word的奧秘

2. Monitor:同步的實質

二、鎖升級的全過程與底層操作

1. 無鎖 -> 偏向鎖

2. 偏向鎖 -> 輕量級鎖

3. 輕量級鎖 -> 重量級鎖

三、高級話題與實戰調優

1. 鎖的優劣對比

2. 鎖降級

? ? ? ? 3. synchronized的性能問題


作為Java并發編程的基石,synchronized?關鍵字的重要性不言而喻。它不僅僅是一個關鍵字,更是一套完整的線程同步解決方案,其背后蘊含著Java虛擬機精湛的設計哲學。本文將帶領你從字節碼層面到操作系統內核,全方位剖析?synchronized?的實現原理、優化手段與實戰技巧。

一、核心機制深度解析

synchronized?的實現建立在兩個核心概念之上:對象頭(Object Header)?和?Monitor(監視器)。理解這兩者是掌握?synchronized?的關鍵。

1. 對象頭(Object Header)與Mark Word的奧秘

每個Java對象在堆內存中的存儲布局都包含以下部分:

  • 對象頭 (Object Header):包含兩類信息:

    • Mark Word:這是實現鎖的核心。在64位JVM中,它通常占64位(8字節),是一個動態變化的數據結構,其內容會根據鎖的狀態而發生改變。它用于存儲對象的哈希碼(hashCode)、GC分代年齡、鎖狀態標志、線程持有的鎖信息、偏向線程ID等。

    • Klass Pointer:指向對象的類元數據(Class對象)的指針,JVM通過它來確定對象屬于哪個類。在64位JVM中,默認開啟指針壓縮(-XX:+UseCompressedOops),此指針被壓縮為32位。

  • 實例數據 (Instance Data):對象真正存儲的有效信息,即程序代碼中定義的各種字段內容。

  • 對齊填充 (Padding):起占位符作用,HotSpot VM要求對象起始地址必須是8字節的整數倍,因此需要對對象大小進行對齊填充。

Mark Word在不同鎖狀態下的結構是其精髓所在,如下圖所示:
(此處應有一張Mark Word內存布局圖,展示無鎖、偏向鎖、輕量級鎖、重量級鎖、GC標記狀態下的位分布)

鎖狀態偏向鎖標志 (biased_lock)鎖標志位 (lock)存儲內容
無鎖001對象的哈希碼(hashCode)、對象分代年齡
偏向鎖101持有偏向鎖的線程ID、epoch、對象分代年齡
輕量級鎖-00指向棧中鎖記錄(Lock Record)的指針
重量級鎖-10指向操作系統互斥量(Mutex)和等待隊列的指針
GC標記-11空(表示該對象正被垃圾回收)

2. Monitor:同步的實質

每個Java對象都可以關聯一個Monitor(監視器鎖)。在HotSpot虛擬機中,Monitor是由?ObjectMonitor?類(C++實現)實現的,其主要數據結構包括:

  • _owner:指向當前持有該Monitor的線程。

  • _EntryList:存儲所有阻塞等待獲取該Monitor的線程。

  • _WaitSet:存儲調用了?Object.wait()?方法而進入等待狀態的線程。

當線程執行到?synchronized?保護的代碼塊時:

  1. 執行?monitorenter?指令,嘗試通過CAS操作將Monitor的?_owner?字段設置為當前線程。

  2. 如果成功,該線程即持有Monitor,進入臨界區執行代碼。

  3. 如果失敗,說明Monitor已被其他線程持有,當前線程會進入?_EntryList?隊列中阻塞等待。

  4. 持有Monitor的線程執行完同步代碼后,會執行?monitorexit?指令,將?_owner?置為?null?并喚醒?_EntryList?中的線程,它們將重新競爭鎖。

二、鎖升級的全過程與底層操作

鎖升級是?synchronized?性能優化的核心,其目的是在無競爭或低競爭情況下,避免使用重量級鎖帶來的高昂開銷。

1. 無鎖 -> 偏向鎖

  • 觸發條件:第一個線程訪問同步塊。

  • 底層操作:JVM使用CAS操作,將當前線程ID寫入對象頭的Mark Word中,并設置偏向鎖標志。如果成功,則線程成功獲取偏向鎖。

  • 優勢:此后該線程再進入同步塊時,只需檢查Mark Word中的線程ID是否為自己,是則直接執行,無需任何同步操作,開銷極小。

2. 偏向鎖 -> 輕量級鎖

  • 觸發條件:有另一個線程來競爭鎖(偏向鎖發生撤銷)。

  • 底層操作

    1. 首先,JVM會暫停擁有偏向鎖的線程。

    2. 然后,在該線程的棧幀中創建一個鎖記錄(Lock Record)?空間。

    3. 將對象當前的Mark Word復制到該線程的鎖記錄中(稱為Displaced Mark Word)。

    4. 線程使用CAS操作嘗試將對象頭的Mark Word替換為指向其鎖記錄的指針。

    5. 如果成功,當前線程獲得輕量級鎖;如果失敗,表示存在競爭,進而升級為重量級鎖

  • 優勢:在沒有真正競爭的情況下,使用CAS這種用戶態操作避免了操作系統內核態切換的開銷。

3. 輕量級鎖 -> 重量級鎖

  • 觸發條件:輕量級鎖的CAS操作失敗(自旋后仍無法獲取鎖)。

  • 底層操作

    1. 當前線程會先自旋一小段時間(自適應自旋),嘗試獲取鎖,以避免直接升級帶來的開銷。

    2. 如果自旋后仍無法獲取,鎖正式升級為重量級鎖。

    3. JVM會向操作系統申請一個互斥量(Mutex),并將對象頭的Mark Word更新為指向該互斥量的指針。

    4. 未能獲取鎖的線程會被掛起(park),進入?_EntryList?隊列,等待操作系統的調度喚醒。

  • 開銷:線程的掛起和喚醒涉及用戶態到內核態的切換,上下文切換成本非常高。

三、高級話題與實戰調優

1. 鎖的優劣對比

鎖類型優點缺點適用場景
偏向鎖加鎖解鎖無額外開銷鎖撤銷有額外開銷單線程訪問同步塊
輕量級鎖競爭線程不阻塞,程序響應快長時間自旋會消耗CPU追求響應時間,同步塊執行快
重量級鎖競爭線程不自旋,不消耗CPU線程阻塞,響應慢追求吞吐量,同步塊執行時間長

2. 鎖降級

鎖降級確實存在,但其場景非常有限,主要發生在?GC的STW階段。為了減少GC停頓時間,JVM會嘗試進行鎖降級。但在正常的用戶代碼執行路徑中,鎖升級是不可逆的,這是為了避免在重量級鎖和輕量級鎖之間反復切換帶來的巨大性能損耗。

3. 性能調優最佳實踐

  • 減少鎖粒度:縮小同步代碼塊的范圍,最經典的例子是?ConcurrentHashMap?使用分段鎖。

  • 減少鎖持有時間:避免在同步塊內執行耗時的I/O操作、網絡請求或復雜計算。

  • 讀寫分離:使用?ReadWriteLock?替代獨占鎖,允許讀讀并發,提高讀多寫少場景的性能。

  • JVM參數調優

    • -XX:-UseBiasedLocking:明確知道會有高競爭時,可禁用偏向鎖

    • -XX:BiasedLockingStartupDelay=0:取消偏向鎖延遲(默認4s),適用于啟動后立即高并發的應用。

    • -XX:+UseSpinning?/?-XX:PreBlockSpin:控制輕量級鎖的自旋策略(JDK6之后是自適應自旋,通常無需手動調整)。

? ? ? ? 3. synchronized的性能問題

  1. 鎖粒度太大:同步范圍覆蓋過多無關代碼,導致線程競爭加劇。
  2. 鎖持有時間過長:同步塊中包含耗時操作。
  3. 鎖競爭激烈:多個線程頻繁爭搶同一把鎖,導致上下文切換頻繁。
  4. 鎖升級頻繁:大量競爭導致鎖從偏向鎖升級到重量級鎖。
  5. 死鎖:線程互相等待對方釋放鎖,導致系統停滯。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/96365.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/96365.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/96365.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

4.1 - 拖鏈電纜(柔性電纜)與固定電纜

本文介紹固定電纜和拖鏈專用線纜的對比、以及使用注意事項。尤其是在伺服的電纜選型上,一定要注意。總結成兩點:1). 在移動場合,一定要選用拖鏈電纜,不要用普通電纜去代替,否則很快就會損壞,甚至造成安全隱…

S32K3平臺eMIOS 應用說明

S32K3 系列 eMIOS 介紹 1.1 資源介紹 該設備具有 3 個 eMIOS 模塊,每個模塊的配置如表 1.1 所示。1.2 功能介紹 eMIOS 提供了用于生成或測量時間事件的功能。它使用 UCs,您可以為不同的芯片應 用中的不同功能進行編程。此外,eMIOS 體系結構允…

Next.js中服務器端渲染 (SSR) 詳解:動態內容與 SEO 的完美結合

Next.js中服務器端渲染 (SSR) 詳解:動態內容與 SEO 的完美結合 作者:碼力無邊在上一篇文章中,我們深入探討了靜態站點生成 (SSG) 的強大之處,它通過在構建時預先生成頁面,為用戶提供了極致的訪問速度。但現實世界是動態…

c# winform 使用DevExpress制作表格

環境配置創建c# winform 新項目 test_devexpress添加引用把DevExpress.XtraGrid.v17.1.dll拖到工具箱在界面中&#xff0c;加入2個 GridControl設計器代碼&#xff1a;namespace test_devexpress {partial class Form1{/// <summary>/// 必需的設計器變量。/// </summ…

數據庫之間如何同步

數據庫之間如何同步&#xff1a;三種高效方法詳解 數據同步無小事&#xff0c;選對方法事半功倍 在現代數據驅動的環境中&#xff0c;??數據庫之間如何同步??是確保業務連續性和數據一致性的核心技術。本文將深入介紹三種主流的數據庫同步方法&#xff0c;幫助您根據實際需…

《我的世界》中實現強化學習(RL)算法

在《我的世界》中實現強化學習&#xff08;RL&#xff09;是一個巨大的挑戰&#xff0c;而獎勵函數&#xff08;Reward Function&#xff09;的設計是其中最核心、最困難的部分&#xff0c;直接決定了算法能否成功學習。 下面我將為你提供一個系統的設計框架、策略和注意事項。…

智能光場:深度學習重構計算光學成像新范式!

1.掌握深度學習算法的原理和應用&#xff0c;剖析計算成像主流研究范圍及關聯的統一計算范式&#xff0c;能夠運用深度學習技術對光學成像系統進行創新設計和優化。2.掌握利用深度學習從成像設備優化設計、典型計算成像任務以及后端的計算機視覺任務的認知框架&#xff0c;并掌…

深入理解 MyBatis-Plus 的 QueryWrapper:動態 SQL 構建的利器

關鍵詞&#xff1a;MyBatis-Plus、QueryWrapper、動態 SQL、Java、ORM 一、引言 在 Java 后端開發中&#xff0c;MyBatis-Plus&#xff08;簡稱 MP&#xff09;作為 MyBatis 的增強工具&#xff0c;極大地簡化了 CRUD 操作。而其中最核心的功能之一&#xff0c;就是動態 SQL 的…

WMIC用法

WMIC用法基本語法結構1. 全局開關&#xff08;可選&#xff0c;控制整體行為&#xff09;2. 別名&#xff08;Alias&#xff09;3. 動詞&#xff08;Verb&#xff09;4. 參數&#xff08;可選&#xff09;常用示例幫助命令WMIC&#xff08;Windows Management Instrumentation …

Spring Boot--yml配置信息書寫和獲取

案例&#xff1a;Spring Boot整合Mybatis步驟一&#xff1a;導入依賴步驟二&#xff1a;添加數據庫需要的數據源配置步驟三&#xff1a;編寫實體類步驟四&#xff1a;創建mapper類&#xff0c;操作數據庫步驟五&#xff1a;創建Service接口和接口實現類步驟六&#xff1a;創建C…

創作紀念日·512天

嘿嘿&#xff0c;不知不覺間&#xff0c;已經到了512天創作紀念日了。 回憶 遙想我在《我的創作紀念日》一篇中寫道&#xff0c;想要改名為 十二 &#xff0c;作為對過去生活的懷念&#xff0c;沒想到這個名字被搶了&#xff0c;好可惜。 想到25年4月13日寫紀念日博客時的自己…

在 Berachain 上,如何通過 BERA 實現一魚多吃?

Berachain 的 PoL&#xff08;Proof of Liquidity&#xff09;機制是其最具辨識度的創新之一。通過將 DeFi 的激勵邏輯深度嵌入共識層&#xff0c;不僅為底層網絡注入了充足的流動性&#xff0c;保障了安全性&#xff0c;同時也有效推動了生態應用的增長&#xff0c;更為用戶創…

LangGraph和aiagent

1. LangGraph&#xff1a;用圖思維重構Agent工作流LangGraph是LangChain團隊開源的圖式Agent編排框架&#xff0c;它基于"有向圖"模型&#xff0c;將Agent的運行流程抽象為"節點 狀態流轉"。其核心設計理念是用有向狀態圖&#xff08;Directed State Grap…

《從iptables到ipvs:云原生網絡轉發的性能拐點突破》

這套基于Spring Cloud Alibaba搭建的架構,部署于阿里云ACK集群的10個4核8G節點上,默認配置6個Pod副本,搭配HPA彈性擴縮容機制與Ingress網關流量分發,理論上具備應對3倍日常流量的承載能力。然而實際運行中,每日早9點、午2點、晚8點三次流量峰值來臨時,訂單服務會在120秒內…

大數據存儲域——Kafka設計原理

摘要本文主要介紹了Kafka的架構原理、消息訂閱模式以及在金融風控等領域的應用。Kafka作為數據中轉站&#xff0c;可同步不同系統數據&#xff0c;支持事件驅動架構&#xff0c;廣泛應用于金融支付與風控場景。其架構包括Producer、Broker、Topic、Partition、Replication、Mes…

[特殊字符] GitHub 熱門開源項目速覽(2025/09/09)

今天為大家整理了近期 GitHub 上熱度較高的開源項目&#xff0c;涵蓋 AI Agent、加密計算、操作系統、機器人、PDF 工具 等多個方向。讓我們一起看看都有哪些值得關注的項目吧&#xff01; &#x1f539; AI Agents & 開發者工具 parlant &#xff08;? 10.9k | ?? 117…

OpenHarmony之USB Manager 架構深度解析

1. 整體架構 OpenHarmony USB管理器采用三層架構設計: USB API:提供USB的基礎API,主要包含查詢USB設備的列表、設備插拔通知、USB HOST/DEVICE 功能切換、批量數據傳輸、控制命令傳輸、USB設備打開的權限控制及USB device模式下的function功能切換等。 USB Service:主要實…

java面試中經常會問到的mysql問題有哪些(基礎版)

文章目錄一、基礎概念與存儲引擎二、索引設計與優化&#xff08;高頻重點&#xff09;三、事務與鎖&#xff08;核心原理&#xff09;四、SQL性能優化與問題排查五、高可用與數據安全六、其他高頻細節問題在Java面試中&#xff0c;MySQL作為最常用的關系型數據庫&#xff0c;是…

Tess-two - Tess-two 文字識別(Tess-two 概述、Tess-two 文字識別、補充情況)

一、Tess-two 概述Tess-two 是 Tesseract OCR 引擎在 Android 平臺上的一個封裝庫&#xff0c;用于實現離線文字識別Tess-two 的 GitHub 官網&#xff1a;https://github.com/rmtheis/tess-two二、Tess-two 文字識別 1、演示 &#xff08;1&#xff09;Dependencies 模塊級 bui…

八、Win/Linux/macOS全平臺徹底卸載Docker的操作指南

八、Win/Linux/macOS全平臺徹底卸載Docker的操作指南 系列文章目錄 1. 卸載前準備工作(可忽略) 1.1 數據備份 1.2 停止Docker服務 2. 不同操作系統卸載步驟 2.1 Linux系統 2.2 macOS系統 2.3 Windows系統 3. 殘留文件深度清理 3.1 Linux系統 3.2 macOS系統 3.3 Windows系統 4…