java单例模式
来源:互联网
时间:2026-07-06 07:26:05
聊到Ja va单例模式,大家可能都不陌生。饿汉式、懒汉式、双重检测锁、静态内部类,还有枚举——实现方式可谓五花八门。不过今天咱们重点聊聊枚举方式,这玩意儿在《Effective Ja va》里也被强烈推荐过,确实有它的独到之处。

一、案例
先来一个最直接的用法示例,三步走,一看就懂。1、新建一个接口类
public interface MySingleton {
void doSomething();
}
2、新建枚举类,实现上面的接口
public enum Singleton implements MySingleton {
INSTANCE {
@Override
public void doSomething() {
System.out.println("执行方法。。。");
}
}
}
3、测试
public class Test {
public static void main(String[] args) {
Singleton.INSTANCE.doSomething();
}
}
这就是枚举实现单例最基础的模样。干净、简单,没有花里胡哨的锁和判断。
二、扩展
仅仅会用还不够,我们得知道它好在哪,以及跟其他方式比有什么优劣。1、枚举方式实现单例的好处
枚举单例最大的优势——天生线程安全,而且绝对防止反射和序列化破坏。你不需要自己写synchronized,也不需要操心反序列化时重新创建对象。Ja va虚拟机从底层就保证了枚举实例的唯一性,这比那些靠代码硬防的方式靠谱得多。
2、四种方式的比较
- :类加载时就创建实例,线程安全,调用效率高,但无法延迟加载。如果这个单例对象很重,又一直没被用到,就白白浪费了内存。
饿汉式
- :第一次调用时才创建实例,能延迟加载,但为了线程安全得加synchronized,调用效率低。在高并发场景下性能堪忧。
懒汉式
- :这也是一种懒加载方式。利用类加载机制保证线程安全,资源利用率高,可以延迟加载。是比较优雅的方案之一。
静态内部类实现方式
- :看似完美,但JVM底层指令重排等问题,导致它偶尔会出bug。实际开发中不推荐。
双重检测锁式
- :线程安全,调用效率高,但无法延迟加载。好在很多场景下单例对象并不大,延迟加载的需求没那么迫切。
枚举式(推荐)
3、总结
1. 饿汉式线程安全,调用效率高,但不能延迟加载。
2. 懒汉式线程安全,调用效率不高,能延迟加载。
3. 双重检测锁式由于JVM底层内部模型原因,偶尔会出问题。不建议使用。
4. 静态内部类式线程安全,资源利用率高,可以延时加载。
5. 枚举单例线程安全,调用效率高,但不能延迟加载。
4、如何选择?
没有银弹,得看场景:
- 如果单例对象占用资源少,不需要延时加载:。枚举的防破坏能力更强。
枚举式 好于 饿汉式
- 如果单例对象占用资源大,需要延时加载:。静态内部类兼顾了延迟加载和性能。
静态内部类式 好于 懒汉式
以上就是对枚举单例的一点梳理。实际项目中,选哪种方式根据自己的资源需求和代码风格来定就好。