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

Java 單例模式雙重檢查鎖與餓漢式代碼實戰

     編輯:Java 相關知識

線程級單例:ThreadLocal 隔離 + 雙重檢查鎖 + 餓漢式結合

針對「每線程一個實例」的場景(如請求上下文、事務管理),結合 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 省略
}

關鍵點解析

改進建議

  • 移除 synchronized 方法鎖,改用 map.get() 為 null 時 map.set(new Instance()),依賴 ThreadLocal 線程隔離天然無併發衝突(每線程獨立初始化)
  • 若需全局單例(非線程級),優先 enum Singleton { INSTANCE } 或靜態內部類
  • 請求級上下文推薦 Spring RequestContextHolder / Transactional 成熟方案
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
機制作用注意事項
ThreadLocal線程隔離存儲用完必須 remove() 防洩漏
雙重檢查鎖延遲初始化+高併發性能實例字段需 volatile(此處由 ThreadLocal 保證可見性)
synchronized(類.class)類級鎖,保護初始化臨界區粒度較粗,可改用實例鎖或 ConcurrentHashMap
餓漢式 static 字段類加載時創建簡單可靠,但無法實現「每線程一實例」