Java多線程知識小結:Synchronized

在Java中,synchronized 關鍵字是實現線程同步的核心工具,用于保證同一時刻只有一個線程可以執行被修飾的代碼塊或方法。以下從基本原理、鎖升級過程、應用場景及優化建議四個維度詳細解析:

一、基本原理

1. 同步的對象

synchronized 鎖的是對象而非代碼:

  • 修飾實例方法:鎖的是當前實例對象(this);
  • 修飾靜態方法:鎖的是類的Class對象(如MyClass.class);
  • 修飾代碼塊:鎖的是括號中的對象(如synchronized(obj))。
2. 底層實現
  • JVM層面:通過對象頭中的Mark Word和**Monitor(監視器)**實現。
    對象頭的Mark Word包含鎖狀態位(如偏向鎖、輕量級鎖、重量級鎖)和指向Monitor的指針。
  • 字節碼層面
    • 同步方法:通過ACC_SYNCHRONIZED標志位標識;
    • 同步代碼塊:通過monitorentermonitorexit指令實現。
3. 互斥鎖語義
  • 線程進入同步塊前需獲取Monitor的所有權(鎖),退出時釋放鎖;
  • 未獲取到鎖的線程會被阻塞,進入Monitor的等待隊列。

二、鎖升級的具體過程

JDK 6之后,synchronized 鎖機制進行了優化,引入鎖升級(偏向鎖 → 輕量級鎖 → 重量級鎖)以減少性能開銷。

1. 偏向鎖(Biased Locking)
  • 適用場景:單線程環境,無鎖競爭。
  • 原理
    1. 首次線程訪問同步塊時,Mark Word存儲該線程ID(偏向狀態);
    2. 后續該線程再次進入同步塊時,無需CAS操作,直接獲取鎖;
    3. 若其他線程嘗試競爭鎖,偏向鎖撤銷,升級為輕量級鎖。
  • 優點:無CAS操作,僅首次獲取鎖時有少量開銷。
  • 缺點:存在鎖撤銷(偏向鎖撤銷需STW),若存在多線程競爭,反而增加開銷。
2. 輕量級鎖(Lightweight Locking)
  • 適用場景:多線程交替執行同步塊(無實際競爭)。
  • 原理
    1. 線程進入同步塊時,JVM在當前線程棧幀中創建鎖記錄(Lock Record)
    2. 通過CAS將對象頭的Mark Word復制到鎖記錄,并將Mark Word指向鎖記錄地址;
    3. 若CAS成功,獲取輕量級鎖;若失敗,說明存在競爭,鎖膨脹為重量級鎖。
  • 優點:競爭不激烈時,避免線程阻塞,減少用戶態/內核態切換。
  • 缺點:競爭激烈時,頻繁CAS導致性能下降。
3. 重量級鎖(Heavyweight Lock)
  • 適用場景:多線程同時競爭鎖。
  • 原理
    1. 鎖膨脹后,Mark Word指向操作系統的Monitor對象
    2. 未獲取到鎖的線程被阻塞(進入內核態),放入Monitor的等待隊列;
    3. 鎖釋放時,喚醒等待隊列中的線程(需從內核態轉回用戶態)。
  • 缺點:線程阻塞/喚醒涉及用戶態與內核態切換,性能開銷大。
4. 鎖升級流程圖
無鎖狀態 → 偏向鎖(單線程) → 輕量級鎖(多線程交替) → 重量級鎖(多線程競爭)
5. 鎖升級的觸發條件
  • 偏向鎖撤銷:當其他線程嘗試訪問偏向鎖對象時,JVM在安全點(Safepoint)撤銷偏向鎖;
  • 輕量級鎖膨脹:線程嘗試CAS獲取輕量級鎖失敗時,鎖膨脹為重量級鎖;
  • 批量重偏向/撤銷:當一個類的對象頻繁發生偏向鎖撤銷時,JVM會對該類的對象批量重偏向或撤銷。

三、應用場景

1. 保護共享資源
  • 示例:多線程操作同一個計數器:
    public class Counter {private int count = 0;// 同步方法,鎖的是thispublic synchronized void increment() {count++;}
    }
    
2. 實現原子操作
  • 示例:雙重檢查鎖定(DCL)實現單例模式:
    public class Singleton {private static volatile Singleton instance; // 必須用volatile禁止指令重排public static Singleton getInstance() {if (instance == null) { // 第一次檢查synchronized (Singleton.class) { // 鎖的是Class對象if (instance == null) { // 第二次檢查instance = new Singleton();}}}return instance;}
    }
    
3. 保證復合操作的原子性
  • 示例:檢查再執行(Check-Then-Act)操作:
    public class Inventory {private Map<String, Integer> stock = new HashMap<>();// 復合操作:先檢查庫存,再扣減public synchronized boolean decreaseStock(String product, int amount) {if (stock.getOrDefault(product, 0) >= amount) {stock.put(product, stock.get(product) - amount);return true;}return false;}
    }
    
4. 線程間協作(wait/notify機制)
  • 示例:生產者-消費者模型:
    public class ProducerConsumer {private final Queue<Integer> queue = new LinkedList<>();private final int CAPACITY = 10;// 生產者方法public synchronized void produce(int item) throws InterruptedException {while (queue.size() == CAPACITY) {wait(); // 等待隊列有空間}queue.add(item);notifyAll(); // 通知消費者有新元素}// 消費者方法public synchronized int consume() throws InterruptedException {while (queue.isEmpty()) {wait(); // 等待隊列有元素}int item = queue.poll();notifyAll(); // 通知生產者有空間return item;}
    }
    

四、優化建議

1. 縮小同步塊范圍
  • 反例
    public synchronized void process() {// 非關鍵代碼long startTime = System.currentTimeMillis();// 關鍵代碼(需要同步)synchronized (this) {// 操作共享資源}// 非關鍵代碼System.out.println("耗時:" + (System.currentTimeMillis() - startTime));
    }
    
  • 正例:僅同步關鍵代碼:
    public void process() {long startTime = System.currentTimeMillis();// 僅同步關鍵代碼synchronized (this) {// 操作共享資源}System.out.println("耗時:" + (System.currentTimeMillis() - startTime));
    }
    
2. 優先使用同步代碼塊而非同步方法
  • 同步方法默認鎖的是this,可能導致鎖范圍過大;
  • 同步代碼塊可精確控制鎖對象。
3. 使用細粒度鎖替代粗粒度鎖
  • 反例
    public class Bank {private Map<String, Account> accounts = new HashMap<>();// 粗粒度鎖:整個方法同步public synchronized void transfer(String from, String to, double amount) {// 轉賬邏輯}
    }
    
  • 正例
    public class Bank {private Map<String, Account> accounts = new HashMap<>();// 細粒度鎖:僅鎖相關賬戶public void transfer(String from, String to, double amount) {Account fromAccount = accounts.get(from);Account toAccount = accounts.get(to);// 按順序加鎖,避免死鎖Account first = fromAccount.hashCode() < toAccount.hashCode() ? fromAccount : toAccount;Account second = first == fromAccount ? toAccount : fromAccount;synchronized (first) {synchronized (second) {// 轉賬邏輯}}}
    }
    
4. 考慮替代方案
  • 原子類(如AtomicInteger)替代簡單計數器的synchronized
  • 讀寫鎖ReentrantReadWriteLock)替代讀多寫少場景的synchronized
  • 并發容器(如ConcurrentHashMap)替代synchronized Map

五、總結

synchronized 關鍵字的核心特點:

  • 優點
    • 使用簡單,無需手動釋放鎖;
    • 鎖升級機制在不同場景下有較好的性能表現;
    • 支持線程間協作(wait/notify)。
  • 缺點
    • 無法中斷正在等待鎖的線程;
    • 不支持超時獲取鎖;
    • 鎖粒度較粗(要么全鎖,要么全放)。

適用場景

  • 簡單的同步需求(如保護共享資源、實現原子操作);
  • 需配合wait/notify實現線程間協作。

在高并發場景下,若性能敏感,可考慮使用ReentrantLockStampedLock等更靈活的鎖機制。

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

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

相關文章

MTK項目wifi.cfg文件如何配置的Tput和功耗參數

下面的MTK參數主要與無線網絡(Wi-Fi)配置相關,特別是與WMM(Wi-Fi Multimedia)和功率控制相關的設置 WMM相關參數: WmmParamCwMax/WmmParamCwMin:定義競爭窗口的最大/最小值,這里設置為10/4,用于控制信道訪問的退避機制13 WmmParamAifsN:仲裁幀間間隔數,設置為3影響不同…

分水嶺算法:圖像分割的浸水原理

分水嶺算法&#xff1a;基于拓撲地貌的邊界提取核心原理 分水嶺算法將圖像視為拓撲地貌&#xff0c;灰度值代表海拔高度。通過模擬浸水過程&#xff1a;局部極小值&#xff1a;對應集水盆&#xff08;區域內部&#xff09;。分水嶺線&#xff1a;集水盆之間的山脊&#xff08;區…

汽車功能安全系統階段開發【技術安全方案TSC以及安全分析】5

文章目錄1 技術安全方案 (Technical Safety Concept - TSC)2 系統安全架構設計 (System Safety Architecture Design)3 如何進行安全分析 (Safety Analysis)4 技術安全需求 (TSR) 如何分配到系統架構1 技術安全方案 (Technical Safety Concept - TSC) 技術安全方案 (Technical…

學習軟件測試的第十二天(接口測試)

一.如果一個接口請求不通&#xff0c;那么你會考慮那些方面的問題&#xff1f;如果一個接口請求不通&#xff0c;我會像“排查水管漏水”一樣一步步定位問題發生在哪一段&#xff0c;主要從這幾個方向去思考&#xff1a;當一個接口請求不通時&#xff0c;我會從以下幾個方面進行…

Linux下的C/C++開發之操作Zookeeper

ZooKeeper C 客戶端簡介與安裝ZooKeeper C API 簡介ZooKeeper 官方提供了多語言客戶端&#xff0c;C 語言客戶端是最底層的實現之一&#xff0c;功能全面且穩定&#xff0c;適合嵌入式開發、系統級組件、C 項目集成等場景。zookeeper.h 是 ZooKeeper 提供的 C 語言客戶端頭文件…

【openp2p】學習3:【專利分析】一種基于混合網絡的自適應切換方法、裝 置、設備及介質

本專利與開源項目無關,但可能是實際商用的一種專利。專利地址從此專利,可見p2p的重要性。透傳服務可能是實時轉發服務,提供中繼能力 透傳服務可以是指一種通過公網服務器將數據從第一客戶端傳遞到另一個設備 或客戶端的服務。這種服務通常用于克服網絡中的障礙,如防火墻、…

OpenCV中DPM(Deformable Part Model)目標檢測類cv::dpm::DPMDetector

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 OpenCV 中用于基于可變形部件模型&#xff08;DPM&#xff09; 的目標檢測器&#xff0c;主要用于行人、人臉等目標的檢測。它是一種傳統的基于特…

macOS 26快捷指令更新,融入AI打造智能操作體驗

快捷指令作為Mac系統中提升用戶操作效率的得力助手&#xff0c;在macOS 26中迎來了一次具有突破性的重大更新。此次更新融入了先進的AI技術&#xff0c;推出“智能操作”&#xff08;Intelligent Actions&#xff09;功能&#xff0c;讓快捷指令從簡單的自動化工具升級為真正的…

InstructBLIP:邁向具備指令微調能力的通用視覺語言模型

溫馨提示&#xff1a; 本篇文章已同步至"AI專題精講" InstructBLIP&#xff1a;邁向具備指令微調能力的通用視覺語言模型 摘要 大規模的預訓練與instruction tuning在構建通用語言模型方面已取得顯著成效。然而&#xff0c;構建通用的視覺-語言模型仍然具有挑戰性&…

基于dropbear實現嵌入式系統ssh服務端與客戶端完整交互

以下基于 Dropbear 實現 SSH 服務端與客戶端交互的完整步驟&#xff0c;涵蓋服務端部署、客戶端連接、認證配置及消息傳輸&#xff0c;結合了多篇權威資料的核心實踐&#xff1a;環境準備與安裝 服務端安裝 ? Linux 系統&#xff08;以 Ubuntu/CentOS 為例&#xff09; Ubuntu…

深圳安銳科技發布國內首款4G 索力儀!讓斜拉橋索力自動化監測更精準高效

近日&#xff0c;深圳安銳科技正式發布國內首款無線自供電、一體化的斜拉索實時監測設備 “4G索力監測儀”&#xff0c;成功攻克了傳統橋梁索體監測領域長期存在的實時性差、布設困難和成本高昂的行業難題&#xff0c;為斜拉橋、系桿拱橋提供全無線、自動化、云端實時同步的索力…

Pipeline 引用外部數據源最佳實踐

場景解析在企業網絡安全日志處理場景中&#xff0c;防火墻、入侵檢測系統&#xff08;IDS&#xff09;等設備會持續產生大量日志&#xff0c;記錄網絡流量、訪問請求、異常事件等基礎信息&#xff0c;但這些原始日志僅能呈現表面現象&#xff0c;難以全面剖析安全威脅&#xff…

UI + MCP Client + MCP Server(并且鏈接多個Server)

項目結構前端項目--------->MCP Client----------->MCP Serverserver就不過多贅述了&#xff0c;他只是相當于添加了多個的tools 鏈接前后端 http.createServer創建一個服務器// ---------------------------------------------------------------- // server.js import …

香港站群服務器與普通香港服務器對比

在選擇香港服務器時&#xff0c;用戶常常會遇到"站群服務器"和"普通服務器"兩種選項&#xff0c;雖然它們都基于香港數據中心的基礎設施&#xff0c;但在 IP 地址配置、功能定位和管理復雜度、成本上存在顯著差異&#xff0c;理解這些差異有助于用戶根據實…

4.B樹和B+樹的區別?為什么MySQL選擇B+樹作為索引?

區別&#xff1a;1.數據存儲位置B樹每個節點都存儲了索引和數據B樹只有葉子節點存儲數據&#xff0c;非葉子節點僅存儲索引2.葉子節點的鏈接B樹的所有葉子節點通過指針連接成一個雙向鏈表&#xff0c;可以高效地進行范圍查詢或者順序遍歷B樹則沒有這樣的連接關系&#xff0c;查…

轉換狂魔,Modbus TCP轉Profinet網關打通視覺傳感線連接之路

在汽車零部件沖壓生產線的世界中&#xff0c;液壓機的壓力穩定性是確保產品質量的秘密武器。然而&#xff0c;舊時代的人工巡檢和傳統監測方式卻好似拖累現代化進程的沉重枷鎖&#xff1a;效率低、成本高&#xff0c;還總是趕不上實時反饋的快車。這時&#xff0c;工廠決心大刀…

C++進階—二叉樹進階

第一章&#xff1a;內容安排說明 map和set特性需要先鋪墊二叉搜索樹&#xff0c;而二叉搜索樹也是一種樹形結構二叉搜索樹的特性了解&#xff0c;有助于更好的理解map和set的特性二叉樹中部分面試題稍微有點難度&#xff0c;在前面講解大家不容易接受&#xff0c;且時間長容易…

驅動下一代E/E架構的神經脈絡進化—10BASE-T1S

汽車電子電氣架構的演進正經歷一場深刻的變革&#xff0c;“中央計算單元區域控制器”的架構模式已成為當前主流車型平臺發展的明確方向。這種從傳統的“功能域”&#xff08;Domain&#xff09;架構向“區域”&#xff08;Zonal&#xff09;架構的轉型升級&#xff0c;旨在實現…

某學校系統中挖礦病毒應急排查

本篇文章主要記錄某學校長期未運營維護的程序&#xff0c;被黑客發現了漏洞&#xff0c;但好在學校有全流量設備&#xff0c;抓取到了過程中的流量包 需要你進行上機以及結合流量分析&#xff0c;排查攻擊者利用的漏洞以及上傳利用成功的木馬 文章目錄靶機介紹1.使用工具分析共…

vue 、react前端頁面支持縮放,echarts、地圖點擊左邊不準的原因和解決辦法

原因 由于以上都是通過canvas畫布生成的&#xff0c;一旦初始化&#xff0c;就會按照比例進行縮放&#xff0c;但與此同時&#xff0c;比例尺并沒有變化&#xff0c;導致坐標偏移 解決辦法 設置一個zoomVal產量&#xff0c;在頁面加載時計算縮放比例&#xff0c;然后在canvas容…