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

Java 多線程同步必要性:臟數據產生原理、JMM 內存模型與原子操作

     編輯:Java 相關知識

變量分類與同步需求

純讀操作一般無需同步。

臟數據經典案例

public static int n = 0;
public void run() {
    int m = n;
    yield();  // 釋放 CPU,放大問題
    m++;
    n = m;
}
// 100線程並發 → n 遠小於 100 (如 59)

臟數據產生過程圖解

  1. Thread1: m = n (0)
  2. Thread1: yield() 釋放 CPU
  3. Thread2: m = n (0) (n 仍為 0)
  4. Thread1/2 先後執行 m++ → n=m,最終 n=1
  5. 100線程重複 → 大量更新丟失

臟數據產生時序圖

n++ 也不是原子操作!

Java 源碼:n++;
字節碼 (7條指令):

aload_0
dup
getfield    // 讀取 n 值到棧
iconst_1
iadd        // +1
putfield    // 寫回 n
return

中間可被打斷,同樣產生臟數據。

Java 內存模型 (JMM) 解釋

  • 主內存:所有實例/靜態變量 (共享)
  • 工作內存:線程私有棧 (局部變量、操作數棧)
  • 操作流程:主存讀取 → 工作內存修改 → 寫回主存
  • 非原子性:讀取/修改/寫回三步可被打斷

解決方案:同步 = 原子操作

強制同一時間僅一線程操作共享變量,將「讀-改-寫」變為不可分割的原子操作。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
類型定義位置共享性需同步
局部變量方法內部線程私有否
類變量 (成員/靜態)類中多線程可見是 (有寫操作時)