You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单例类是否真的需要双重检查锁定?同步块单判断实现存疑

关于单例模式中双重检查锁定的常见疑问

嘿,这个问题问到点子上了——很多开发者在实现懒加载单例时,都会在“要不要用双重检查锁定”以及“简化版锁实现行不行”这两个问题上纠结。咱们逐个理清楚:

1. 单例类中的双重检查锁定是否真的有必要?

答案是:取决于你的需求场景。

双重检查锁定(DCL)的核心目的是同时满足两个诉求:

  • 懒加载:只有当第一次调用getInstance()时才初始化单例对象,避免类加载时就占用资源(比如单例对象体积大、初始化成本高);
  • 高性能:避免每次获取实例都进入同步代码块——一旦单例对象被初始化后,后续所有调用都不需要再抢锁,直接返回实例即可。

如果你的场景不需要懒加载(比如单例对象很小,初始化成本可以忽略),那直接用饿汉式实现就好,完全没必要搞DCL:

public class Singleton {
    private static final Singleton singleton = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() {
        return singleton;
    }
}

但如果必须懒加载,同时又在意高并发下的性能,那DCL就是非常必要的优化手段——它能把同步的开销降到最低。

2. 能不能仅在synchronized块中加入if判断?这个实现有问题吗?

先看你给出的代码:

public static Singleton getInstance() { 
    synchronized(Singleton.class) { 
        if (singleton == null) { 
            singleton = new Singleton(); 
        } 
    } 
    return singleton; 
}

先说结论:这个实现是线程安全的,但性能问题非常严重。

为什么线程安全?

因为所有调用getInstance()的线程都必须先获取Singleton.class的锁,同一时间只有一个线程能进入同步块,所以不会出现多个线程同时初始化singleton的情况,保证了单例的唯一性。

但问题出在哪?

性能!性能!性能!
每次调用getInstance(),不管singleton有没有被初始化,线程都要先去抢锁、释放锁——锁的获取和释放是有开销的,在高并发场景下,大量线程会因为等待锁而阻塞,这会让你的代码运行效率大打折扣。

而双重检查锁定就是为了解决这个问题:在同步块外面先加一层非同步的if (singleton == null)判断。这样一来,当singleton已经初始化后,后续线程根本不需要进入同步块,直接返回实例,完全避免了锁的开销。

另外补充个小知识点:在JDK 1.5之前,DCL存在指令重排序的问题(singleton = new Singleton()会被JVM拆分成“分配内存→初始化对象→赋值引用”三步,重排序后可能变成“分配内存→赋值引用→初始化对象”,导致其他线程拿到未完全初始化的实例)。所以JDK 1.5及以后,必须给singleton加上volatile关键字,禁止指令重排序,才能让DCL真正安全:

public class Singleton {
    private volatile static Singleton singleton; // 必须加volatile
    private Singleton() {}
    public static Singleton getInstance() {
        if (singleton == null) { // 第一次检查,无锁
            synchronized(Singleton.class) {
                if (singleton == null) { // 第二次检查,有锁
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

内容的提问来源于stack exchange,提问作者Rex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:31:03