单例模式(Singleton): 保证一个类只有一个实例,并且提供一个全局访问点。
- 场景:重量级的对象,不需要多个实例,如线程池、数据库连接池。
- 优点:某些类创建频繁,这是一笔很大的系统开销。 省去new操作符,降低系统内存的使用频率,减轻GC压力。
- 懒汉模式: 延迟加载,只有真正使用的时候,才开始实例化。
- 线程安全问题
- double check 加锁优化
- 编译器(JIT)、CPU有可能对指令进行重排序,导致使用到尚未初始化的实例,可以使用volatile关键字修饰。
class HelloSingLeton {
private static HelloSingLeton instance = new HelloSingLeton();
private HelloSingLeton (){}
public static synchronized HelloSingLeton getInstance(){
if (instance == null) {
synchronized(HelloSingLeton.class){
if (instance == null) {
instance = new HelloSingLeton();
}
}
}
return instance;
}
}
- 饿汉模式: 类加载,只有真正使用的时候,才触发初始化。
- 初始化阶段就完成了实例的初始化,本质上就是借助JVM类加载机制,保证实例的唯一性。
class HelloSingLeton {
private static HelloSingLeton instance = new HelloSingLeton();
private HelloSingLeton (){
if (HelloSingLeton.instance != null) {
throw new RuntimeException("禁止使用反射创建多个单例对象");
}
}
public static synchronized HelloSingLeton getInstance(){
return instance;
}
}