Skip to content

源码:labs/java/runtime-concurrency/singleton-dcl/src/SynchronizedSingleton.java

  • 原始路径:labs/java/runtime-concurrency/singleton-dcl/src/SynchronizedSingleton.java
  • 类型:java
java
/**
 * 方法级 synchronized 的懒汉式单例。
 *
 * 特点:
 * - 懒加载:第一次 getInstance() 才创建
 * - 线程安全:✅ synchronized 保证只初始化一次且安全发布
 * - 性能:🐢 实例已存在后,每次 get 仍竞争类锁,吞吐低于 DCL / 静态内部类
 * - 复杂度:低,语义直观,适合入门理解「加锁换安全」
 *
 * Java 场景:
 * - 低并发、getInstance() 调用不频繁的工具类(勉强可用)
 * - 教学:演示「整方法同步」与 DCL「仅首次同步」的差异
 * - ❌ 高 QPS 热点路径、线程池密集获取单例时不推荐
 *
 * Android 场景:
 * - 偶尔访问的全局管理器可工作,但不如静态内部类常见
 * - UI 线程频繁 getInstance() 可能无谓争用类锁
 * - 现代项目更倾向 Hilt @Singleton 或 Kotlin object,而非手写此方法同步
 *
 * 代价:
 * - 实例创建后每次调用仍走 synchronized,无「双重检查」减负
 *
 * 如何运行:
 * - javac -d out src/*.java
 * - java -cp out SynchronizedSingleton
 *
 * 预期输出:
 * - 两次输出应是同一个对象,same instance = true
 */
public class SynchronizedSingleton {
    private static SynchronizedSingleton instance;

    private SynchronizedSingleton() {
    }

    public static synchronized SynchronizedSingleton getInstance() {
        if (instance == null) {
            instance = new SynchronizedSingleton();
        }
        return instance;
    }

    public static void main(String[] args) {
        SynchronizedSingleton a = SynchronizedSingleton.getInstance();
        SynchronizedSingleton b = SynchronizedSingleton.getInstance();
        System.out.println(a);
        System.out.println(b);
        System.out.println("same instance = " + (a == b));
    }
}