单例模式的破坏者包括克隆和多线程竞争:克隆因未重写clone()方法可绕过构造器生成新实例;多线程竞争在未同步懒汉式中导致多次初始化。

单例模式里的“破坏者”,指的是那些绕过常规 getInstance 逻辑、直接生成新实例的机制。除了反射和序列化,还有两个明确且常见的破坏方式:克隆和多线程竞争。
克隆(Clone)
如果单例类实现了 Cloneable 接口,又没重写 clone() 方法,调用 clone() 就会绕过私有构造器,直接复制内存对象——得到一个全新实例,且 hash 值不同。
- 解决办法:在单例类中重写 clone() 方法,强制返回 getInstance() 结果
- 不建议实现 Cloneable,除非有明确需求且已做好防护
多线程竞争(懒汉式未同步)
在未加锁的懒汉式实现中,多个线程同时判断 instance == null 成立,就会各自执行 new 操作,造成多次初始化。
- 这不是“恶意破坏”,但客观上打破了单例契约
- 典型表现:getInstance() 返回了不同对象,尤其在高并发压测时容易复现
- 修复方式包括:加 synchronized、双重检查锁(DCL)、静态内部类、枚举等线程安全方案
其他潜在风险点
虽不属主流“破坏者”,但需留意:
- 构造器未私有化:外部直接 new,属于设计疏漏,不是技术绕过
- 类加载器隔离:同一类被不同 ClassLoader 加载,会产生多个“单例”——它们彼此不可见,但在 JVM 层是不同类
- 反序列化 + readResolve 缺失:本质仍属序列化范畴,但常被忽略为独立风险点
真正可靠的单例,得同时扛住这几种路径。枚举方式之所以被推崇,正因为它天然免疫反射、克隆和序列化三类破坏。

















