首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java volatile 關鍵字:正確理解與使用指南

     編輯:Java 相關知識

volatile 核心作用

volatile 確保變量對所有線程的可見性:一線程修改後,其他線程立即可見最新值。但不保證原子性(如 i++ 仍非原子)。

為什麼需要 volatile?

現代 CPU 多級緩存導致線程讀到舊值。以 i++ 為例,實際分三步:

  1. 讀取主存到寄存器
  2. 寄存器加1
  3. 寫回主存

多線程環境下,可能線程A讀取後未寫回,線程B讀到舊值,導致更新丟失。volatile 強制每次讀寫直接操作主存,禁用緩存優化。

長整型/雙精度型的非原子性

32位系統下,long/double 佔64位,寫入需兩次32位操作。無 volatile 時,可能出現「高32位新、低32位舊」的數據撕裂。volatile 保證 64 位讀寫原子性。

使用規則與限制

  • 可修飾任何非 final 變量(final 不可變,無需 volatile)
  • 不適用於需複合操作的場景(如計數器、check-then-act)
  • 不加鎖,性能優於 synchronized,但功能較弱
  • 禁止指令重排序(JMM happens-before 語義)

適用場景

  1. 狀態標誌:volatile boolean shutdown = false; 線程輪詢退出
  2. 單次寫入、多次讀取:配置參數、一次性初始化結果
  3. 雙重檢查鎖定(DCL):配合 volatile 修正單例模式指令重排

錯誤用法示例

// 錯誤:volatile 不保證 i++ 原子性
volatile int counter = 0;
public void increment() { counter++; } // 仍有競爭條件

// 正確:使用 AtomicInteger 或 synchronized
AtomicInteger counter = new AtomicInteger(0);
public void increment() { counter.incrementAndGet(); }

深度參考資源

強烈推薦閱讀 IBM DeveloperWorks 經典文章:《Java 理論與實踐: 正確使用 Volatile 變量》,對 volatile 語義、內存屏障、JMM 模型有極深入闡述。

出處:https://lavasoft.blog.51cto.com/62575/222076

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved