針對「每線程一個實例」的場景(如請求上下文、事務管理),結合 ThreadLocal 隔離性與雙重檢查鎖延遲初始化,附餓漢式靜態字段對比。
class MyThreadScopeData {
// 餓漢式:類加載時創建,線程安全、無鎖開銷、但可能浪費(若從未使用)
private static MyThreadScopeData instance = null;
// ThreadLocal 存儲線程專屬實例
private static final ThreadLocal<MyThreadScopeData> map =
ThreadLocal.withInitial(() -> null); // JDK 8 懶加載
private MyThreadScopeData() {} // 私有構造器
// 雙重檢查鎖獲取線程實例
public static synchronized MyThreadScopeData getThreadInstance() {
MyThreadScopeData inst = map.get();
if (inst == null) { // 第一次檢查
synchronized (MyThreadScopeData.class) { // 類級鎖
inst = map.get();
if (inst == null) { // 第二次檢查
inst = new MyThreadScopeData();
map.set(inst);
}
}
}
return inst;
}
// 業務字段
private String name;
private int age;
// getter/setter 省略
}
| 機制 | 作用 | 注意事項 |
|---|---|---|
| ThreadLocal | 線程隔離存儲 | 用完必須 remove() 防洩漏 |
| 雙重檢查鎖 | 延遲初始化+高併發性能 | 實例字段需 volatile(此處由 ThreadLocal 保證可見性) |
| synchronized(類.class) | 類級鎖,保護初始化臨界區 | 粒度較粗,可改用實例鎖或 ConcurrentHashMap |
| 餓漢式 static 字段 | 類加載時創建 | 簡單可靠,但無法實現「每線程一實例」 |