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

Java 並發編程實戰核心:對象安全發佈與共享模式

     編輯:Java 綜合教學

Java 並發編程實戰核心:對象安全發佈與共享模式

多線程環境下,對象從構建到被其他線程可見的「發佈」過程若處理不當,會導致可見性問題、部分構造狀態洩露。本文系統梳理三大核心模式:棧封閉、不可變性、安全發佈四種模式。

一、棧封閉 —— 最簡單的線程安全

public void processRequest(Request req) {
    // 局部變量:每線程獨有棧幀,天然隔離
    List localList = new ArrayList<>();
    Map localMap = new HashMap<>();
    
    // 業務邏輯...
    localList.add(req.getParam());
    
    // 方法返回,局部變量隨棧幀銷毀,無發佈風險
}

核心原則:對象引用永不逃逸出方法/線程邊界。無同步開銷,性能最優。

二、不可變性 —— 天然線程安全

    模式代碼示例適用場景內存語義
    1. 靜態初始化public static final Config INSTANCE = new Config();單例、常量、類加載階段構造Class 初始化鎖保證 Happens-Before
    2. volatile 引用private volatile Config config;運行期熱更新、單寫多讀volatile 寫-讀 Happens-Before
    3. final 域public final Config config = new Config();構造後不可變引用final 域寫入-構造函數結束 Happens-Before (JMM)
    4. 鎖保護synchronized(map) { map.put(k, v); }可變共享狀態、複合操作解鎖-加鎖 Happens-Before


反面教材:不安全發佈

// 危險:非 final、非 volatile、無鎖
public Holder holder;  

public void initialize() {
    holder = new Holder(42);  // 線程 A
}

// 線程 B 可能看到 holder != null 但 holder.n == 0 (部分構造狀態)
public void use() {
    if (holder != null) {
        System.out.println(holder.n);
    }
}

實戰檢查清單

  1. 對象是否需要跨線程共享?否 → 棧封閉
  2. 共享對象構造後是否不可變?是 → 不可變模式 + 任意發佈
  3. 可變共享對象 → 必須選擇四種安全發佈模式之一
  4. 檢查構造過程中 this 是否逃逸 (註冊回調、啟動線程、拋出異常)
  5. 使用 @ThreadSafe/@NotThreadSafe/@GuardedBy 註解文檔化線程安全承諾

掌握發佈與逸出核心概念,配合 JMM Happens-Before 規則,是編寫正確並發程序的基石。《Java Concurrency in Practice》第 3 章詳述此體系,強烈建議精讀。

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