单例模式(Singleton Pattern)
确保一个类只有一个实例,并对外提供统一的访问方式
分类
- 饿汉模式:类被加载时就立即初始化并创建唯一实例
- 懒汉模式:被客户端首次调用时才创建唯一实例
1)加入双重检查锁检测机制来保证懒汉模式的线程安全
2)枚举单例模式来防止反射入侵
饿汉模式
/**
* 饿汉模式
*/
public class StarvingSingleton {
/**
* 类加载时就实例化
* 私有的构造函数,与类实例
*/
private static final StarvingSingleton starvingSingleton = new StarvingSingleton();
private StarvingSingleton(){ }
/**
* 获取实例的唯一入口
* @return 实例
*/
public static StarvingSingleton getInstance(){
return starvingSingleton;
}
}
饿汉模式
public class LazyDoubleCheckSingleton {
/**
* volatile 保证其可见性与禁止重排序
*/
private volatile static LazyDoubleCheckSingleton instance;
private LazyDoubleCheckSingleton(){}
/**
* synchronized:保证其原子性
* 双重检查锁检测机制:保证线程操作资源过程不被打断
* @return
*/
public static LazyDoubleCheckSingleton getInstance(){
//第一次检测
if (instance==null){
//同步
synchronized (LazyDoubleCheckSingleton.class){
if (instance == null){
/*
对象初始化的三个步骤
memory = allocate(); //1.分配对象内存空间
instance(memory); //2.初始化对象
instance = memory; //3.设置instance指向刚分配的内存地址,此时instance!=null
*/
instance = new LazyDoubleCheckSingleton();
}
}
}
return instance;
}
枚举单例
/**
* 通过反射可以直接入侵类的私有构造函数,实例化类的对象;
* 枚举类无法通过反射入侵,因此能够解决上述问题;
*/
public class EnumStarvingSingleton {
private EnumStarvingSingleton(){}
public static EnumStarvingSingleton getInstance(){
return ContainerHolder.HOLDER.instance;
}
private enum ContainerHolder{
HOLDER;
private EnumStarvingSingleton instance;
ContainerHolder(){
instance = new EnumStarvingSingleton();
}
}
}
单例模式确保类只有一个实例,并提供全局访问点。饿汉模式在类加载时初始化实例,而懒汉模式在首次调用时创建。为解决懒汉模式的线程安全问题,可以使用双重检查锁,但最佳实践是通过枚举实现单例,这同时避免了反射攻击。

被折叠的 条评论
为什么被折叠?



