本文目录导读:

我为您整理了单例模式的多种经典写法,每种都有其适用场景和优缺点。
饿汉式(静态常量)
public class SingletonEager {
// 类加载时就创建实例
private static final SingletonEager INSTANCE = new SingletonEager();
private SingletonEager() {}
public static SingletonEager getInstance() {
return INSTANCE;
}
}
优点:简单,线程安全
缺点:类加载时就创建实例,可能造成资源浪费
饿汉式(静态代码块)
public class SingletonStaticBlock {
private static SingletonStaticBlock instance;
static {
instance = new SingletonStaticBlock();
}
private SingletonStaticBlock() {}
public static SingletonStaticBlock getInstance() {
return instance;
}
}
适用场景:可以在静态代码块中添加更多初始化逻辑
懒汉式(线程不安全)
public class SingletonLazy {
private static SingletonLazy instance;
private SingletonLazy() {}
public static SingletonLazy getInstance() {
if (instance == null) { // 单线程环境可用
instance = new SingletonLazy();
}
return instance;
}
}
缺点:多线程环境下不安全,不推荐使用
懒汉式(同步方法)
public class SingletonLazySync {
private static SingletonLazySync instance;
private SingletonLazySync() {}
public static synchronized SingletonLazySync getInstance() {
if (instance == null) {
instance = new SingletonLazySync();
}
return instance;
}
}
优点:线程安全
缺点:每次调用都需要同步,性能较低
双重检查锁(DCL)
public class SingletonDCL {
// volatile 防止指令重排序
private static volatile SingletonDCL instance;
private SingletonDCL() {}
public static SingletonDCL getInstance() {
if (instance == null) { // 第一次检查
synchronized (SingletonDCL.class) {
if (instance == null) { // 第二次检查
instance = new SingletonDCL();
}
}
}
return instance;
}
}
优点:线程安全,性能较好
注意:必须使用volatile关键字
静态内部类(推荐)
public class SingletonHolder {
private SingletonHolder() {}
// 静态内部类,调用getInstance时才会加载
private static class SingletonInstance {
private static final SingletonHolder INSTANCE = new SingletonHolder();
}
public static SingletonHolder getInstance() {
return SingletonInstance.INSTANCE;
}
}
优点:
- 线程安全(类加载机制保证)
- 懒加载(使用时才加载内部类)
- 性能好
枚举方式(最佳实践)
public enum SingletonEnum {
INSTANCE; // 枚举元素本身就是单例
private String name = "singleton";
public void showMessage() {
System.out.println("枚举单例: " + name);
}
// 使用方式
public static void main(String[] args) {
SingletonEnum.INSTANCE.showMessage();
}
}
优点:
- 最简单
- 线程安全
- 防反射攻击
- 防序列化破坏
完整对比代码(含测试)
public class SingletonDemo {
public static void main(String[] args) {
// 测试各种单例
testSingleton("饿汉式", SingletonEager::getInstance);
testSingleton("静态代码块", SingletonStaticBlock::getInstance);
testSingleton("懒汉式", SingletonLazySync::getInstance);
testSingleton("双重检查锁", SingletonDCL::getInstance);
testSingleton("静态内部类", SingletonHolder::getInstance);
testSingleton("枚举", () -> SingletonEnum.INSTANCE);
// 多线程测试
testThreadSafety();
}
private static void testSingleton(String name, Supplier<Object> supplier) {
Object s1 = supplier.get();
Object s2 = supplier.get();
System.out.println(name + " 是否为单例: " + (s1 == s2));
}
private static void testThreadSafety() {
// 测试DCL是否线程安全
ExecutorService pool = Executors.newFixedThreadPool(10);
Set<SingletonDCL> set = ConcurrentHashMap.newKeySet();
for (int i = 0; i < 100; i++) {
pool.execute(() -> set.add(SingletonDCL.getInstance()));
}
pool.shutdown();
System.out.println("DCL线程安全测试 实例数量: " + set.size());
}
}
选型建议
-
最优选:枚举方式(
SingletonEnum)最简洁,天然线程安全,防止反射和序列化破坏
-
项目中常用:静态内部类(
SingletonHolder)实现简单,性能好,懒加载
-
注重性能:双重检查锁(
SingletonDCL)性能好,但注意volatile使用
-
简单场景:饿汉式(
SingletonEager)类不复杂,无资源浪费时使用
-
避免使用:纯懒汉式(非线程安全)
完整演示代码(可直接运行)
import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Supplier; // 在这里加入上面所有的单例类... // 然后运行 SingletonDemo 测试
这8种写法覆盖了Java单例模式的所有经典实现,您可以根据实际项目需求选择最合适的方式,在实际开发中,枚举和静态内部类是最高效、最安全的推荐方案。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播