java单例模式实现(归纳)

1.定义

单例模式,属于创建型模式的一种。在应用这个模式时,单例对象的类必须保证只有一个实例存在。

 

2.常见单例模式实现

饿汉式

public class SingletonStatic {
    private static final SingletonStatic instance = new SingletonStatic();

    private SingletonStatic(){
    }

    public static SingletonStatic getSingleton(){
        return instance;
    }
}

特点:提前加载,线程安全

懒汉式

public class SingletonLazy {

    private volatile static SingletonLazy instance;

    private SingletonLazy(){}

    public static SingletonLazy getSingleton(){
        if (instance == null){
            synchronized (SingletonLazy.class){
                if(instance == null){ //二次检查
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }
}

特点:懒加载,线程安全

ps: instance变量用volatile是为了杜绝 JVM 的指令重排对单例造成的影响,二次检查实现线程安全

 

3.进阶(防止反序列化和反射攻击)

使用枚举实现单例,防止反序列化和反射攻击

public enum SingletonEnum {

    singletonFactory;

    private Singleton instance;

    private SingletonEnum(){//枚举类的构造方法在类加载时被实例化
        instance = new Singleton();
    }

    public Singleton getInstance(){
        return instance;
    }
}

class Singleton{//需要获实现单例的类
    public Singleton(){}
}

 

非枚举的防守方法

(1)防止反射

增加一个标志变量,在构造函数中检查是否已被调用过,若已被调用过,将抛出异常,保证构造函数只被调用一次:

public class Singleton {
    private static Singleton instance;
    private static boolean isInstance = false;

    private Singleton() {
        synchronized (Singleton.class) {
            if (!isInstance) {
                isInstance = true;
            } else {
                throw new RuntimeException("单例模式受到反射攻击!已成功阻止!");
            }
        }
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

 

(2)防止序列化

增加一个 readResolve 方法并返回 instance 对象。当 ObjectInputStream类反序列化时,如果对象存在 readResolve 方法,则会调用该方法返回对象。

public class Singleton implements Serializable {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    private Object readResolve() {
        return instance;
    }
}

 

参考文章:

https://juejin.im/post/6844904058583875592

https://juejin.im/post/6844903801111986190

https://blog.csdn.net/u011277123/article/details/104523638

https://blog.csdn.net/cselmu9/article/details/51366946

 

posted @ 2020-09-27 20:06  yifanglai  阅读(157)  评论(0)    收藏  举报