Skip to content

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

  • 原始路径:labs/java/runtime-concurrency/singleton-dcl/src/BadSingleton.java
  • 类型:java
java
/**
 * 错误示例:最朴素的懒汉式单例(无同步)。
 *
 * 特点:
 * - 懒加载:第一次 getInstance() 才 new
 * - 线程安全:❌ 多线程可能创建多个实例,或看到未安全发布的引用
 * - 性能:无锁,但语义错误,不能用于生产
 * - 复杂度:最低,仅作反例对照
 *
 * Java 场景:
 * - ❌ 任何多线程环境(Web 服务、线程池、并发工具类)均不可用
 * - 仅适合理解「单线程 main 看起来正常 ≠ 并发安全」的教学演示
 *
 * Android 场景:
 * - ❌ 主线程 + 后台线程、协程、Handler 并发下同样不安全
 * - 面试/代码评审中的典型反模式:复制粘贴懒汉式却忘记同步
 *
 * 为什么它是错误示例:
 * - 多线程同时通过外层 if (instance == null) 时会重复 new
 * - 无 volatile / 同步,不保证安全发布,可能读到半初始化对象
 *
 * 应改用:静态内部类、enum(无参)、或 DCL + volatile(需懒加载传参时)
 *
 * 如何运行:
 * - javac -d out src/*.java
 * - java -cp out BadSingleton
 *
 * 预期输出:
 * - 单线程 main 中两次输出通常 same instance = true
 * - 不能证明线程安全;并发语义仍然错误
 */
public class BadSingleton {
    private static BadSingleton instance;

    private BadSingleton() {
    }

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

    public static void main(String[] args) {
        BadSingleton a = BadSingleton.getInstance();
        BadSingleton b = BadSingleton.getInstance();
        System.out.println(a);
        System.out.println(b);
        System.out.println("same instance = " + (a == b));
        System.out.println("注意:单线程输出为 true,不代表并发下安全");
    }
}