转载自:https://blog.csdn.net/qq_38584967/article/details/88910479
设计模式名称 | 属性 |
懒汉式单例模式 | 线程安全,调用效率不高,但是可以延时加载。 |
饿汉式单例模式 | 线程安全,调用效率高,但是不是延时加载。 |
静态内部类实现单例模式(推荐): | 线程安全,调用效率高,并且可以延时加载。 |
枚举实现单例模式 (推荐): | 线程安全,调用效率高,不延时加载,防反射和反序列化漏洞。 |
双重检测得单例模式 | 线程安全,调用效率不高,用来防止缓存击穿 |
懒汉式单例模式: 线程安全,调用效率不高,但是可以延时加载。
/**
* 懒汉式,先不创建实例,等到需要时在创建。
* 多线程情况下并发效率低。
* 结论:线程安全,调用效率不高,但是可以延时加载。
*/
public class LazySingleton {
/**
* 静态实例变量
*/
private static LazySingleton instance;
/**
* 私有构造函数
*/
private LazySingleton() {
}
/**
*懒汉式创建实例,需要同步处理
* @return
*/
public static synchronized LazySingleton getInstance(){
if (instance == null){
instance = new LazySingleton();
}
return instance;
}
}
饿汉式单例模式: 线程安全,调用效率高,但是不是延时加载。
/**
* 饿汉式,类初始化时立即加载这个对象,
* 如果加载这个对象耗时间长并且这个对象没有被使用,得不偿失。
* 结论:线程安全,调用效率高,但是不是延时加载。
*/
public class HungrySingleton {
/**
* 静态实例对象
*/
private static HungrySingleton instance = new HungrySingleton();
/**
* 私有的构造函数
*/
private HungrySingleton() {
}
/**
* 静态方法并不需要做同步处理
* @return
*/
public static HungrySingleton getInstance(){
return instance;
}
}
静态内部类实现单例模式(推荐): 线程安全,调用效率高,并且可以延时加载。
/**
* 静态内部类实现单例模式(懒加载的一种)
* 静态内部类只有在调用的时候才初始化,并且初始化过程线程安全。
* instance不提供修改实例方法,静态变量只初始化一次,所以final修饰不加也一样。
* 兼备了并发高效调用和懒加载的优势。
* 结论:线程安全,调用效率高,并且可以延时加载。
*/
public class StaticClassSingleton {
//私有构造函数
private StaticClassSingleton(){};
//静态内部类
private static class SingletonClassInstance{
private static final StaticClassSingleton INSTANCE =
new StaticClassSingleton();
}
//提供实例的调用方法
public static StaticClassSingleton getInstance(){
return SingletonClassInstance.INSTANCE;
}
}
枚举实现单例模式 (推荐): 线程安全,调用效率高,但是不是延时加载,天然防止反射和反序列化漏洞。
/**
* 枚举类对象本身就是一个单例对象。
* 没有延时加载的特性。
* 可以天然的防止反射和反序列化的漏洞,因为枚举是基于JVM底层实现的。
* 结论:线程安全,调用效率高,但是不是延时加载,天然防止反射和反序列化漏洞。
*/
public enum EnumSingleton {
/**
* 枚举对象
*/
INSTANCE;
/**
* 成员方法
*/
public void singletonOperation(){
//单例对象的其它操作实现。
}
}
双重检测得单例模式(不建议使用)
/**
* 懒汉式实现的一种
* 但是由于编译器优化的原因和JVM底层内部模型原因,偶尔会出现问题
* 结论:不建议使用。
*/
public class DoubleCheckLocking {
/**
* 懒汉式,加上volatile,因为线程创建对象有三步
* 1、new开辟空间 //2、构造 初始化对象信息 //3、返回对象的地址给引用
* volatile防止指令重排序,导致2步骤没执行完3步骤便返回的引用。
*/
private static volatile DoubleCheckLocking instance;
/**
* 私有的构造函数
*/
private DoubleCheckLocking(){
}
/**
* 双重检测的单例模式
* @return
*/
public static DoubleCheckLocking getInstance() {
//非空返回,不走同步块,提高效率
if (null == instance) {
synchronized (DoubleCheckLocking.class) {
if (null == instance) {
instance = new DoubleCheckLocking();
}
}
}
return instance;
}
}