本文目录导读:

Java 静态内部类实现单例模式是线程安全且延迟加载的经典做法,它利用了 Java 类加载机制(类加载时才会初始化静态内部类)和 final 字段的线程安全性。
以下是具体的案例代码及详细解释:
标准写法
public class Singleton {
// 1. 私有化构造方法,防止外部直接 new
private Singleton() {
// 可以在这里做一些初始化操作
System.out.println("Singleton 实例被创建");
}
// 2. 公有的静态获取实例方法
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
// 3. 静态内部类(核心)
// 只有当 getInstance() 方法被调用时,此类才会被 JVM 加载
private static class SingletonHolder {
// 4. 在静态内部类中持有外部类的唯一实例
// 该变量在类加载时被初始化,且由 JVM 保证线程安全性
private static final Singleton INSTANCE = new Singleton();
}
// 为了演示效果,添加一个业务方法
public void doSomething() {
System.out.println("执行单例对象的方法");
}
}
客户端测试代码
public class Main {
public static void main(String[] args) {
// 验证是否为同一个对象
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println("instance1 == instance2: " + (instance1 == instance2)); // 输出 true
// 测试方法调用
instance1.doSomething();
}
}
进阶:带参数的单例
单例通常是无状态的,但有时需要传递配置参数,静态内部类也可以支持:
public class ConfigSingleton {
private final String value;
// 私有构造方法带参数
private ConfigSingleton(String value) {
this.value = value;
}
public static ConfigSingleton getInstance(String configValue) {
// 避免在第一次 getInstance() 时传入不同的值
return SingletonHolder.INSTANCE;
}
// 注意:这种方式第一次初始化后,参数就固定了
public String getValue() {
return value;
}
private static class SingletonHolder {
// 需要你预先知道默认值,或者通过某种方式设置
private static final ConfigSingleton INSTANCE = new ConfigSingleton("defaultConfig");
}
}
为什么这种方式是线程安全的?
- 类加载机制:
SingletonHolder是一个内部类,只有在getInstance()方法被第一次调用时,JVM 才会加载SingletonHolder类。 - 初始化锁:JVM 在类加载期间会获取一个初始化锁,保证类的
<clinit>()方法(包含静态字段初始化和静态代码块)只会被一个线程执行一次。 final关键字:INSTANCE被static final修饰,保证了可见性和不可变性,所有线程看到的一定是初始化完全的对象。
对比其他单例模式
| 特点 | 饿汉式 | 懒汉式(DCL双重检查锁定) | 静态内部类 |
|---|---|---|---|
| 延迟加载 | ❌ (类加载时就创建) | ✅ | ✅ |
| 线程安全 | ✅ | ✅ (需小心实现) | ✅ (最简洁安全) |
| 实现复杂度 | 低 | 中(需用 volatile + synchronized) | 低 |
| 可能的问题 | 浪费内存 | 代码易出错 | 无法传参(初始化后) |
- 优点:代码清晰,性能高,无锁开销,线程绝对安全。
- 适用场景:大多数需要延迟加载的单例场景。
- 最佳实践:不需要考虑参数传递的通用单例,推荐直接使用这种写法。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播