Java中的鎖升級機制

目錄

核心思想

Java對象頭(Object Header)與Mark Word

鎖升級的詳細步驟

1. 無鎖(No Lock)

2. 偏向鎖(Biased Locking)

3. 輕量級鎖(Lightweight Lock)

4. 重量級鎖(Heavyweight Lock)

流程圖

總結與意義


這是一個非常重要的概念,它主要是針對?synchronized?關鍵字在JVM層面的優化,目的是為了在保證線程安全的同時,盡量減少獲取鎖和釋放鎖帶來的性能開銷。

核心思想

鎖升級的核心思想是:JVM會根據實際運行時鎖的競爭情況,動態地將鎖從低開銷的狀態升級為高開銷、高保障的狀態。

在Java早期版本中,synchronized?的實現非常直接,被稱為“重量級鎖”,性能較差。但從?HotSpot JDK 1.6?開始,JVM團隊對?synchronized?進行了重大優化,引入了偏向鎖輕量級鎖,以及鎖升級的概念,使得它的性能得到了極大的提升,現在在很多場景下已經不再比?ReentrantLock?慢很多。

Java對象頭(Object Header)與Mark Word

要理解鎖升級,首先要知道Java對象在內存中的布局。每個Java對象在堆內存中都有一個對象頭

對象頭主要包含兩部分:

  1. Mark Word:存儲對象自身的運行時數據,如哈希碼、GC分代年齡、鎖狀態標志等。這是鎖升級機制的核心。

  2. Klass Pointer:指向對象元數據的指針,JVM通過它來確定對象是哪個類的實例。

鎖的狀態信息就記錄在?Mark Word?中。鎖升級的過程,其實就是Mark Word中內容變化的過程。


鎖升級的詳細步驟

鎖的升級路徑是單向的,從低到高:無鎖 -> 偏向鎖 -> 輕量級鎖 -> 重量級鎖。這個過程是不可逆的。

1. 無鎖(No Lock)
  • 狀態:一個新創建的對象,還沒有任何線程來競爭它。

  • Mark Word:存儲對象的哈希碼、分代年齡等信息。鎖標志位為?01

2. 偏向鎖(Biased Locking)
  • 設計初衷:在沒有實際競爭只有一個線程多次使用鎖的場景下,消除整個同步的開銷(比如?StringBuffer?的很多方法都是?synchronized?的,但通常只會在單線程中使用)。

  • 工作原理:當第一個線程訪問同步塊時,JVM會將鎖置為偏向模式,并在Mark Word中記錄這個線程的ID。之后這個線程再次進入和退出同步塊時,不需要進行任何CAS操作來加鎖和解鎖,只需要簡單檢查一下Mark Word中是否存儲著自己的線程ID。

  • 升級觸發條件:一旦有另一個線程來嘗試獲取這個鎖(發生了競爭),偏向鎖就會失效。

  • 鎖標志位01?(同時有額外位標識是否為偏向模式)。

可以把它想象成“貼標簽”:第一個線程來了,在對象上貼了個標簽“此物歸我所有”。以后它再來,看到自己的標簽就直接用了。直到有另一個人也想來用,標簽就被撕掉。

注意:由于維護偏向鎖本身也有開銷,且在實際多線程環境中,真正的無競爭場景并不多,從JDK 15開始,偏向鎖已被默認禁用。但理解它對于理解整個鎖升級體系依然至關重要。

3. 輕量級鎖(Lightweight Lock)
  • 設計初衷:當鎖確實存在競爭,但競爭的激烈程度很低(即線程幾乎是交替執行,沒有同時搶鎖),避免直接使用重量級鎖帶來的巨大開銷。

  • 工作原理

    1. 當線程要獲取鎖時,JVM會在當前線程的棧幀中創建一個名為鎖記錄(Lock Record)的空間。

    2. 將對象頭的Mark Word復制到鎖記錄中(稱為Displaced Mark Word)。

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

    4. 如果CAS成功,當前線程就獲得了鎖,此時鎖標志位變為?00

    5. 如果CAS失敗(說明其他線程已經在競爭這個鎖了),當前線程會嘗試自旋(循環重試)來獲取鎖。

  • 升級觸發條件:如果自旋了一定次數后(JVM有自適應策略,自旋次數不固定)還沒有獲得鎖,或者自旋期間又有第三個線程來競爭,輕量級鎖就會膨脹為重量級鎖。

  • 鎖標志位00

可以把它想象成“搶凳子”:大家(線程)禮貌地轉著圈(自旋)等凳子(鎖),誰先坐下誰就用。但如果等太久或者人太多,游戲規則就變了。

4. 重量級鎖(Heavyweight Lock)
  • 設計初衷:處理高激烈度的鎖競爭場景。

  • 工作原理:此時鎖會向操作系統內核申請互斥量(Mutex)。未能獲取到鎖的線程會被掛起(進入阻塞狀態),并放入一個等待隊列中。當鎖被釋放時,操作系統會負責喚醒等待隊列中的線程,讓它們重新競爭鎖。

  • 開銷:這個過程中涉及用戶態到內核態的切換、線程的掛起和喚醒,是開銷最大的一種鎖狀態。

  • 鎖標志位10

可以把它想象成“正式排隊”:沒拿到鎖的人不再自己傻等,而是去休息室(等待隊列)睡覺(阻塞),由管理員(操作系統)叫號喚醒。


流程圖

下圖清晰地展示了鎖升級的全過程:

總結與意義

  1. 優化目的:鎖升級是一種“按需付費”的優化機制。JVM會根據競爭的激烈程度,從低開銷的方案開始嘗試,只有在不得已時才會使用開銷最大的方案。這極大地提高了?synchronized?在常見場景下的性能。

  2. 不可逆性:鎖只能升級,不能降級。這是為了節省在激烈競爭環境下不必要的降級開銷。

  3. 實際應用:對于開發者來說,這個過程是完全透明的,由JVM自動完成。我們只需要安心使用?synchronized?關鍵字,JVM會在背后為我們選擇最優的鎖方案。

  4. 與ReentrantLock的對比ReentrantLock?的實現更類似于“一開始就是重量級鎖”的思路(雖然它也在用戶態做了很多優化,如CAS自旋),但它提供了更靈活的功能(如可中斷、公平鎖等)。而?synchronized?的優勢在于語法簡潔和JVM的自動優化。

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

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

相關文章

Scikit-learn Python機器學習 - 特征預處理 - 標準化 (Standardization):StandardScaler

鋒哥原創的Scikit-learn Python機器學習視頻教程: 2026版 Scikit-learn Python機器學習 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili 課程介紹 本課程主要講解基于Scikit-learn的Python機器學習知識,包括機器學習概述,特征工程(數據…

windows下wsl2 ubuntu開發配置

配置環境變量# 設置方式 命令/文件 生效范圍 適用場景 # 臨時 export FORCE_UNSAFE_CONFIGURE1 當前終端 臨時編譯軟件 # 用戶級永久 ~/.bashrc或~/.profile 當前用戶 長期使用(單用戶) # 系統級永久 /etc/environment或/…

網絡編程 05:UDP 連接,UDP 與 TCP 的區別,實現 UDP 消息發送和接收,通過 URL 下載資源

一、概述 記錄時間 [2025-09-02] 前置文章: 網絡編程 01:計算機網絡概述,網絡的作用,網絡通信的要素,以及網絡通信協議與分層模型 網絡編程 02:IP 地址,IP 地址的作用、分類,通過 …

告別線纜束縛!AirDroid Cast 多端投屏,讓分享更自由

AirDroid Cast 是一款功能強大的跨平臺投屏應用,能夠輕松實現手機、電腦之間以及手機之間的屏幕共享與控制。無論是工作演示、在線教學還是游戲直播,AirDroid Cast 都能提供流暢穩定的投屏體驗。 1. 下載與安裝 您可以通過以下鏈接下載 AirDroid Cast&…

從零開始學大模型之大模型訓練流程實踐

大模型訓練流程實踐 本文較長&#xff0c;建議點贊收藏&#xff0c;以免遺失。更多AI大模型開發 學習視頻/籽料/面試題 都在這>>Github<< >>Gitee<< 6.1 模型預訓練 在上一章&#xff0c;我們逐步拆解了 LLM 的模型結構及訓練過程&#xff0c;從零手…

一文從零部署vLLM+qwen0.5b(mac本地版,不可以實操GPU單元)

第一步&#xff1a;下載anaconda for mac https://zhuanlan.zhihu.com/p/350828057 知乎保姆級教程 https://www.anaconda.com/docs/getting-started/anaconda/install#macos-linux-installation 下載地址 第二步&#xff1a;部署vllm的虛擬環境 https://www.53ai.com/news/Op…

Go語言Range用法全解析

引言Go 語言中的 range 關鍵字是集合遍歷的核心語法結構&#xff0c;它提供了一種高效且類型安全的方式來迭代各種數據結構。range 的設計完美體現了 Go 語言的工程哲學 - 通過最小化的語法提供最大化的功能。標準庫中的許多關鍵組件&#xff08;如 sync.Map、bufio.Scanner 等…

mysql進階語法(視圖)

1、視圖概念 是從一個或多個表中導出來的表&#xff0c;它是一種虛擬存在的表&#xff0c;表的結構和數據都依賴于基本表 應用場景&#xff1a; 多個地方用到同樣的查詢結果該查詢結果用到復雜的select語句 視圖優點&#xff1a; 簡化查詢語句&#xff1a;簡化用戶的查詢操作&a…

編程范式:提升抽象能力的思維工具

這是一個編程中的核心概念&#xff0c;它代表了編寫程序的一套基本風格、方法論和哲學。學習不同的編程范式&#xff0c;就像學習用不同的工具和思維方式來解決問題&#xff0c;能極大地提升你作為程序員的抽象能力和解決問題的能力。一、什么是編程范式&#xff1f;編程范式 是…

阿里云-基于通義靈碼實現高效 AI 編碼 | 1 | 在 Visual Studio Code 中安裝和使用靈碼

文章目錄一、在 Visual Studio Code 中安裝和使用靈碼1.1 準備工作1.2 在 Visual Studio Code 安裝通義靈碼1.3 登錄阿里云賬號免費個人運維知識庫&#xff0c;歡迎您的訂閱&#xff1a;literator_ray.flowus.cn 一、在 Visual Studio Code 中安裝和使用靈碼 本安裝步驟適用于…

WordPress搭建個人網站(Linux版)

WordPress搭建個人網站&#xff0c;使用Linux系統。我需要詳細說明整個過程&#xff0c;包括環境準備、安裝步驟、配置優化等。首先&#xff0c;用戶可能對Linux不太熟悉&#xff0c;所以需要從基礎開始&#xff0c;比如選擇合適的Linux發行版&#xff0c;如Ubuntu或CentOS。然…

ES模塊(ESM)、CommonJS(CJS)和UMD三種格式

vite的build.lib配置生成了三種格式&#xff1a;ES模塊&#xff08;ESM&#xff09;、CommonJS&#xff08;CJS&#xff09;和UMD。它們的主要區別和適用場景如下&#xff1a; ES模塊&#xff08;.mjs&#xff09;&#xff1a; 使用現代JavaScript的模塊語法&#xff08;import…

2026屆IC秋招聯蕓科技IC面經(完整面試題)

聯蕓科技2026屆數字IC后端面經數字后端培訓實戰項目六大典型后端實現案例 首先是自我介紹。這個每家公司必備環節。這部分內容需要自己提前準備&#xff0c;避免太過緊張影響發揮。 數字IC后端經典筆試題IC秋招筆試題之時序報告解析 1&#xff09;拿到netlist和sdc后你會如何…

一維水動力模型有限體積法(四):高級實現——平衡源項、邊界條件與算法總成

引言 成功實現一個穩定且精確的水動力學模型&#xff0c;關鍵在于妥善處理源項和邊界條件。這兩個環節是數值格式產生非物理振蕩和誤差的主要來源。本章將詳細介紹“守恒-平衡”&#xff08;well-balanced&#xff09;格式的核心技術&#xff0c;以及通過“虛擬單元”實現各類物…

VAE(變分自動編碼器)技術解析

VAE&#xff08;Variational Auto-Encoder, 變分自動編碼器&#xff09;1、VAE的結構為什么使用重參數化&#xff1f;2、VAE的代碼實現1.重構損失&#xff08;Reconstruction Loss&#xff09;2.KL散度&#xff08;Kullback-Leibler Divergence Loss&#xff09;1&#xff09;E…

嵌入式單片機---串口通信及相關通信技術

一、通信方式分類&#xff08;一&#xff09;按數據傳輸線路數量劃分&#xff1a;串行通信與并行通信類別定義特點并行通信多個比特同時通過并行線進行傳輸優點&#xff1a;傳輸速率較高&#xff1b;缺點&#xff1a;占用大量芯片資源串行通信將數據拆分成一個個比特&#xff0…

Elasticsearch面試精講 Day 8:聚合分析與統計查詢

【Elasticsearch面試精講 Day 8】聚合分析與統計查詢 文章標簽&#xff1a;Elasticsearch, 聚合查詢, 統計分析, Aggregations, 面試, 大數據, 搜索引擎, 后端開發, 數據分析 文章簡述&#xff1a; 本文是“Elasticsearch面試精講”系列的第8天&#xff0c;聚焦聚合分析與統計…

HTML HTML基礎(2)

1.開發者文檔W3C官網&#xff1a; www.w3c.org W3School&#xff1a; www.w3school.com.cn MDN&#xff1a; developer.mozilla.org —— 推薦。2.排版標簽標簽名標簽含義單 / 雙 標簽h1 ~ h6標題雙p段落雙div沒有任何含義&#xff0c;用于整體布局雙(1). h1 最好寫一個&#x…

spring.profiles.active配置的作用

1. spring.profiles (或文件名中的 ?)&#xff1a;定義配置的名稱這是聲明一段配置屬于哪個 Profile。在同一個 application.yml 中&#xff1a;使用 spring.profiles 鍵來為一個配置段打上標簽。yamlspring:profiles: dev # 【定義】這個配置段的名稱是‘dev’ server:port: …

【開題答辯全過程】以 高校教室管理系統為例,包含答辯的問題和答案

個人簡介一名14年經驗的資深畢設內行人&#xff0c;語言擅長Java、php、微信小程序、Python、Golang、安卓Android等開發項目包括大數據、深度學習、網站、小程序、安卓、算法。平常會做一些項目定制化開發、代碼講解、答辯教學、文檔編寫、也懂一些降重方面的技巧。感謝大家的…