class A {
new Thread(() -> {
int a = 1;
B b = new B();
b.invokeB(a);
});
}
class B {
public void invokeB(int a) {
C c = new C();
c.invokeC(); // 這裡想用 a,但不想層層傳參
}
}
class C {
public void invokeC() {
// 需要取得 a 的值
}
}
開發者希望在同一執行緒的呼叫鏈 A → B → C 中,無需修改方法簽名即可取得變數 a。
ThreadLocal<T> 提供執行緒區域變數:每個執行緒持有獨立的副本,互不干擾。適用於「請求範圍」資料傳遞(如使用者 ID、追蹤 ID、資料庫連線)。
public class ContextHolder {
private static final ThreadLocal VALUE_HOLDER = new ThreadLocal<>();
public static void set(Integer value) { VALUE_HOLDER.set(value); }
public static Integer get() { return VALUE_HOLDER.get(); }
public static void clear() { VALUE_HOLDER.remove(); } // 必須清理,防記憶體洩漏
}
class A {
public void start() {
new Thread(() -> {
ContextHolder.set(1); // 1. 寫入
try {
new B().invokeB();
} finally {
ContextHolder.clear(); // 3. 清理
}
}).start();
}
}
class B {
public void invokeB() { new C().invokeC(); }
}
class C {
public void invokeC() {
Integer a = ContextHolder.get(); // 2. 讀取
System.out.println("取得值: " + a); // 輸出: 取得值: 1
}
}
remove(),舊資料會殘留導致記憶體洩漏與業務錯誤。Integer、String 等不可變型別,避免多處修改同一物件引發副作用。new Thread(() -> ...) 場景。StructuredTaskScope 讓值在作用域內自然流動,無需 ThreadLocal。ThreadLocal 是「同執行緒跨層傳值」的經典利器,但必須嚴格配對 set/remove,且僅適用於同步阻塞模型。現代專案建議優先評估框架內建的上下文傳遞機制,降低手動管理風險。