Appearance
源码: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,不代表并发下安全");
}
}