Java高頻面試之并發編程-17


volatile 和 synchronized 的區別

在 Java 并發編程中,volatilesynchronized 是兩種常用的同步機制,但它們的適用場景和底層原理有顯著差異。以下是兩者的詳細對比:


1. 核心功能對比

特性volatilesynchronized
原子性不保證復合操作的原子性(如 i++)。保證代碼塊或方法的原子性。
可見性強制變量讀寫直接操作主內存,保證可見性。通過鎖的釋放/獲取強制同步內存,保證可見性。
有序性禁止指令重排序(內存屏障)。通過鎖規則保證臨界區內的操作有序性。
線程阻塞無阻塞,輕量級。可能引發線程阻塞(鎖競爭時)。
適用場景單寫多讀、狀態標志。復合操作、臨界區資源保護。

2. 原子性

  • volatile

    • 不保證原子性,僅確保單次讀/寫操作的原子性。
    • 示例
      volatile int count = 0;
      count++; // 非原子操作(實際是 read-modify-write)
      
      多線程并發時,count++ 可能導致數據競爭。
  • synchronized

    • 保證原子性,鎖內的所有操作作為一個整體執行。
    • 示例
      synchronized (lock) {count++; // 原子操作
      }
      

3. 可見性

  • volatile

    • 通過內存屏障強制線程每次讀寫 volatile 變量時直接操作主內存,跳過工作內存(CPU 緩存)。
    • 示例
      volatile boolean flag = true;
      // 線程1修改 flag 后,線程2立即可見
      
  • synchronized

    • 線程進入同步塊時清空工作內存,從主內存重新加載變量;退出同步塊時將變量寫回主內存。
    • 示例
      synchronized (lock) {// 操作共享變量
      }
      

4. 有序性

  • volatile

    • 通過插入內存屏障(StoreStoreStoreLoad 等)禁止編譯器和處理器對 volatile 變量的讀寫操作進行重排序。
    • 示例:雙重檢查鎖定(DCL)中防止對象未初始化就被引用。
      private static volatile Singleton instance;
      
  • synchronized

    • 通過“鎖規則”實現有序性:同一時刻只有一個線程能執行同步塊,天然保證操作按代碼順序執行。
    • 示例
      synchronized (lock) {// 臨界區內的操作不會重排序到鎖外
      }
      

5. 性能開銷

  • volatile

    • 輕量級:僅通過內存屏障限制重排序,無線程阻塞和上下文切換開銷。
    • 適用場景:適合低競爭或單寫多讀場景(如狀態標志)。
  • synchronized

    • 重量級:涉及鎖競爭、內核態切換(重量級鎖)和線程阻塞,開銷較大。
    • 優化機制:鎖升級(偏向鎖 → 輕量級鎖 → 重量級鎖)減少無競爭時的開銷。
    • 適用場景:高競爭或需要復合原子操作的場景(如計數器、資源池)。

6. 底層實現

  • volatile

    • 內存屏障:JVM 在字節碼層面插入屏障指令(如 StoreStoreLoadLoad)。
    • 硬件支持:依賴 CPU 的緩存一致性協議(如 MESI)強制刷新內存。
  • synchronized

    • Monitor 機制:基于對象頭的 Mark Word 實現鎖狀態管理(無鎖、偏向鎖、輕量級鎖、重量級鎖)。
    • 內核態操作:重量級鎖依賴操作系統的互斥量(Mutex)實現線程阻塞。

7. 實際應用示例

(1) volatile 適用場景
  • 狀態標志
    volatile boolean shutdownRequested = false;
    public void shutdown() { shutdownRequested = true; }
    public void doWork() { while (!shutdownRequested) { /* ... */ } }
    
  • 單例模式(DCL)
    public class Singleton {private static volatile Singleton instance;public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
    }
    
(2) synchronized 適用場景
  • 線程安全的計數器
    public class Counter {private int count = 0;public synchronized void increment() { count++; }public synchronized int getCount() { return count; }
    }
    
  • 資源池管理
    public class ConnectionPool {private final LinkedList<Connection> pool = new LinkedList<>();public synchronized Connection getConnection() {while (pool.isEmpty()) wait();return pool.removeFirst();}public synchronized void release(Connection conn) {pool.addLast(conn);notifyAll();}
    }
    

8. 總結對比表

維度volatilesynchronized
原子性僅單次讀/寫原子,不保證復合操作。保證代碼塊或方法的原子性。
可見性直接操作主內存,強制刷新。通過鎖同步內存。
有序性禁止指令重排序。通過鎖規則保證臨界區有序。
線程阻塞無阻塞。可能阻塞(鎖競爭時)。
性能開銷低。高(尤其是重量級鎖)。
適用場景狀態標志、單例模式(DCL)。復合操作、資源競爭、線程間協作。

選擇建議

  • 使用 volatile 的情況

    • 變量被多個線程訪問,但只有一個線程修改。
    • 需要禁止指令重排序(如 DCL 單例模式)。
  • 使用 synchronized 的情況

    • 需要原子性操作(如 i++、復合邏輯)。
    • 多線程競爭同一資源(如連接池、計數器)。

image.png

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

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

相關文章

技術債務積累,如何進行有效管理

識別和評估技術債務、明確技術債務的優先級、制定系統的還債計劃、持續監控與預防技術債務產生是有效管理技術債務積累的重要策略。其中尤其要注重識別和評估技術債務&#xff0c;只有準確識別技術債務的種類和嚴重程度&#xff0c;才能制定出高效且有針對性的解決方案&#xf…

安裝windows版本的nacos

一、下載nacos安裝包 瀏覽器搜索nacos&#xff0c;進入nacos官網 https://nacos.io/docs/latest/overview/ 選擇下載windows版本的nacos 二、解壓縮 三、進入bin目錄&#xff0c;cmd命令行窗口 四、啟動nacos 查看日志 五、打開可視化頁面查看 以上&#xff0c;就是安裝wind…

小結:Android系統架構

https://developer.android.com/topic/architecture?hlzh-cn Android系統的架構&#xff0c;分為四個主要層次&#xff1a;應用程序層、應用框架層、庫和運行時層以及Linux內核層。&#xff1a; 1. 應用程序層&#xff08;Applications&#xff09; 功能&#xff1a;這一層包…

鴻蒙5.0項目開發——鴻蒙天氣項目的實現(歡迎頁)

【高心星出品】 文章目錄 歡迎頁面效果數據字典創建數據庫表格Splash頁面頁面功能歡迎頁代碼亮點 項目按照從數據庫連接層–視圖層–業務邏輯層這種三層架構開發&#xff0c;所以先設計了數據庫表格的結構&#xff0c;在EntryAbility中創建表格。 歡迎頁面效果 數據字典 sear…

使用譜聚類將相似度矩陣分為2類

使用譜聚類將相似度矩陣分為2類的步驟如下&#xff1a; 構建相似度矩陣&#xff1a;提供的1717矩陣已滿足對稱性且對角線為1。 計算度矩陣&#xff1a;對每一行求和得到各節點的度&#xff0c;形成對角矩陣。 計算歸一化拉普拉斯矩陣&#xff1a;采用對稱歸一化形式 LsymI?D…

MySQL 8.0 OCP 英文題庫解析(三)

Oracle 為慶祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免費考取原價245美元的MySQL OCP 認證。 從今天開始&#xff0c;將英文題庫免費公布出來&#xff0c;并進行解析&#xff0c;幫助大家在一個月之內輕松通過OCP認證。 本期公布試題16~25 試題16:…

【SQL】如何在 SQL 中統計結構化字符串的特征頻率

在數據分析場景中&#xff0c;我們經常會遇到需要解析結構化字符串并統計特征出現次數的需求。本文將以常用數據庫為例&#xff0c;探討如何高效處理類似 [特征A][特征B][特征C] 格式的字符串數據&#xff0c;并實現特征頻率統計。以下是完整的實現思路和解決方案。 一、問題場…

Docker Compose 的安裝方法

以下是 Docker Compose 的安裝方法整理&#xff0c;綜合了多篇指南的推薦步驟和注意事項&#xff1a; 一、安裝前準備 確保已安裝 Docker Docker Compose 依賴 Docker 引擎運行&#xff0c;需先安裝 Docker。若未安裝&#xff0c;可通過以下命令一鍵安裝&#xff08;國內服…

配置Nginx解決http host頭攻擊漏洞【詳細步驟】

前言 大概內容&#xff1a; 安全系統滲透測試出host頭攻擊漏洞&#xff0c;下面是解決步驟&#xff0c;本人已測過無問題。 server_name aaabbb.com; if ($http_Host !~* ^127.0.0.1|aaabbb.com|localhost$){return 403;}

自研時序大模型講解(4月29日)直播回顧

4 月 29 日&#xff0c;清華團隊揭秘&#xff1a;時序大模型如何讓數據“活”起來線上直播圓滿結束。清華大學軟件學院博士生&#xff0c;IoTDB 原生機器學習引擎 AINode 研發同學劉雍在線上面向數千人次的時序數據分析人員與 AI 大模型行業關注者&#xff0c;就時序大模型的發…

attention_weights = torch.ones_like(prompt_embedding[:, :, 0]):切片操作獲取第二維度,第三維度

attention_weights = torch.ones_like(prompt_embedding[:, :, 0]):切片操作獲取第1 維度,第二維度 attention_weights = torch.ones_like(prompt_embedding[:, :, 0]) 這行代碼的作用是創建一個與 prompt_embedding[:, :, 0] 形狀相同且所有元素都為 1 的張量,它用于初始化…

鴻蒙Next API17新特性學習之如何使用新增鼠標軸事件

今天咱們接著學習鴻蒙開發文檔API17版本的新特性——對鼠標軸事件的支持。這對于需要精細交互的應用來說是一個非常有用的特性&#xff0c;例如地圖滾動、文檔瀏覽等場景。本文將詳細介紹在鴻蒙 Next 中如何使用新增的鼠標軸事件。 開發步驟 環境準備 在開始開發之前&#x…

【行為型之命令模式】游戲開發實戰——Unity可撤銷系統與高級輸入管理的架構秘鑰

文章目錄 ?? 命令模式&#xff08;Command Pattern&#xff09;深度解析一、模式本質與核心價值二、經典UML結構三、Unity實戰代碼&#xff08;可撤銷的建造系統&#xff09;1. 定義命令接口與接收者2. 實現具體命令3. 命令管理器&#xff08;Invoker&#xff09;4. 客戶端使…

計算機網絡|| 路由器和交換機的配置

一、實驗目的 1. 了解路由器和交換機的工作模式和使用方法&#xff1b; 2. 熟悉 Cisco 網絡設備的基本配置命令&#xff1b; 3. 掌握 Cisco 路由器的基本配置方式及配置命令&#xff1b; 4. 掌握路由器和交換機的基本配置與管理方法。 二、實驗環境 1. 運行 Windows 操作…

面試--HTML

1.src和href的區別 總結來說&#xff1a; <font style"color:rgb(238, 39, 70);background-color:rgb(249, 241, 219);">src</font>用于替換當前元素&#xff0c;指向的資源會嵌入到文檔中&#xff0c;例如腳本、圖像、框架等。<font style"co…

CVPR2025 | Prompt-CAM: 讓視覺 Transformer 可解釋以進行細粒度分析

Prompt-CAM: Making Vision Transformers Interpretable for Fine-Grained Analysis 摘要-Abstract引言-Introduction方法-Approach預備知識-PreliminariesPrompt-CAM: Prompt Class Attention Map特征識別與定位-Trait Identification and Localization變體與擴展-Variants an…

動態規劃問題 -- 多狀態模型(粉刷房子)

目錄 動態規劃分析問題五步曲題目概述代碼編寫 動態規劃分析問題五步曲 不清楚動態規劃分析問題是哪關鍵的五步的少年們可以移步到 鏈接: 動態規劃算法基礎 這篇文章非常詳細的介紹了動態規劃算法是如何分析和解決問題的 題目概述 鏈接: 粉刷房子 狀態表示&#xff08;題目要求…

Spring Boot 注解詳細解析:解鎖高效開發的密鑰

一、引言 Spring Boot 以其快速開發、自動配置等特性&#xff0c;成為構建 Java 應用程序的熱門框架。而注解在 Spring Boot 中扮演著至關重要的角色&#xff0c;它們如同魔法指令&#xff0c;簡化了配置流程&#xff0c;增強了代碼的可讀性與可維護性。本文將深入剖析 Spring…

【Python】抽象基類ABC

抽象基類(Abstract Base Classes)的核心作用 抽象基類(ABC)是Python中一種特殊的類&#xff0c;它通過abc模塊實現&#xff0c;主要服務于面向對象編程中的接口規范和設計約束。以下是它的核心作用&#xff1a; 1. 強制接口實現&#xff08;核心作用&#xff09; 確保子類必…

[python] Python單例模式:__new__與線程安全解析

一 實例的創建過程 我們之前了解過在構造一個類的實例化對象時,會默認調用__init__方法&#xff0c;也就是類的初始化也叫構造函數&#xff0c;但其實在調用__init__方法前會首先調用__new__方法&#xff08;只有在py3新式類才有&#xff09;。即下面 __new__(): 創建實例 作…