浅析Java中的五种单例模式
摘要
单例模式是我们经常接触也是最熟悉的设计模式之一,本文将介绍五种单例模式的实现方式,浅析Java实现单例模式的最好方式
双重检查DCL(多线程安全)(推荐使用)(不能避免反射攻击)
class Singleton{
//使用volatile保证有序性,避免出现singleton还没有从初始化就已经分配引用的情况
private static volatile Singleton singleton;
private Singleton(){};
public Singleton getSingleton(){
if (singleton==null){
//多个线程进来抢夺锁
synchronized(Singleton.class){
抢到锁的线程初始化实例
if (singleton==null){
singleton=new Singleton();
}
}
}
return singleton;
}
}
静态内部类(使用类加载机制保证多线程安全)(不能避免反射攻击)
public class Singleton {
private Singleton(){
}
public static Singleton getSingleton(){
return Inner.instance;
}
private static class Inner {
private static final Singleton instance = new Singleton();
}
}
懒汉式(多线程不安全)
public class Singleton {
//懒体现在不是直接创建单例,是在需要时手动调用getInstance方法创建
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
饿汉式(多线程不安全)
public class Singleton {
饿体现在加载类时就创建好了实例,调用getInstance方法时直接返回
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
枚举(多线程安全)(能够避免反射攻击)
public class SingletonObject {
private SingletonObject(){
}
/**
* 枚举类型是线程安全的,并且只会装载一次
* 反编译枚举类会发现底层是使用到了static final使用类加载机制保证线程安全的
* 关于避免反射问题,枚举使用了特殊的序列化方式避免反射攻击,具体不再赘述
*/
private enum Singleton{
INSTANCE;
private final SingletonObject instance;
Singleton(){
instance = new SingletonObject();
}
private SingletonObject getInstance(){
return instance;
}
}
public static SingletonObject getInstance(){
return Singleton.INSTANCE.getInstance();
}
}

浙公网安备 33010602011771号