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

Java transient 關鍵字與 volatile 混淆辨析:正確理解序列化與並發語義

     編輯:Java 相關知識

網絡上大量文章將 transient(序列化控制)與 volatile(並發可見性)混為一談,甚至誤將 volatile 的說明貼在 transient 下。本文專門釐清兩者本質區別,正確講解 transient 在序列化中的作用,並補充 volatile 的正確語義,避免概念污染。

核心結論:兩者毫無關係

transient 正確用法回顧

class User implements Serializable {
    private String name;
    private transient String password; // 序列化時忽略,反序列化後為 null
    private transient Logger log;      // 非串行化資源
}
  • 序列化:password、log 不寫入字節流。
  • 反序列化:兩字段自動賦默認值(null)。
  • 需在 readObject 中手動恢復(如重建 Logger、解密密碼)。

volatile 正確語義(補充)

volatile 保證:可見性(寫入立即刷新主內存,讀取立即從主內存讀取)+ 有序性(禁止指令重排優化)。不保證原子性(如 volatile int i; i++ 仍非線程安全)。

經典適用場景:狀態標誌

class TaskRunner {
    private volatile boolean stopped = false; // 線程 A 修改,線程 B 可見
    public void run() {
        while (!stopped) { doWork(); }
    }
    public void stop() { stopped = true; }
}

雙重檢查鎖 (DCL) 單例

public class Singleton {
    private static volatile Singleton instance; // 禁止指令重排:分配內存 → 初始化 → 賦值
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) instance = new Singleton();
            }
        }
        return instance;
    }
}

為什麼會混淆?

  1. 名稱相似:都以 trans 開頭,英文單詞皆為「短暫/揮發」含義。
  2. 早期技術博客轉載鏈條中,有人誤將 volatile 代碼/註釋貼在 transient 文章下,被大量複製傳播。
  3. 部分教材未對比講解,導致初學者混淆。

記憶錨點

  • transient → serialization(序列化):trans = transfer/transmit 傳輸時跳過。
  • volatile → visibility(可見性):volatile → volatile memory(易揮發內存)→ 每次直達主存。

源碼級驗證

HashMap.modCount (transient)

transient int modCount; // 結構修改計數,反序列化歸零合理

CopyOnWriteArrayList (volatile)

private volatile Object[] array; // 寫入新數組引用,讀線程立即可見

總結

transient = 序列化開關;volatile = 並發可見性開關。 兩者解決完全不同領域的問題,切勿混淆。遇到「不想序列化」用 transient;遇到「多線程共享變量可見性」用 volatile(或更高級的 Atomic*/Lock)。技術傳播中,請以官方規範(JLS、JVM Spec)為準,拒絕二手轉載誤導。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
維度transientvolatile
所屬領域對象序列化/持久化多線程內存可見性/指令重排
作用目標實例字段(不參與序列化)實例/靜態字段(主內存讀寫)
核心語義「此字段不持久化/不傳輸」「每次讀寫直達主內存,禁止緩存/重排」
典型場景密碼、Logger、衍生字段狀態標誌、雙重檢查鎖、單例 DCL
JVM 層面ObjectOutputStream 跳過該字段內存屏障、緩存一致性協議(MESI)