最优雅的单例模式:

/*
 * 枚举法单例模式
 * */
public enum Singleton {

    SINGLETON("test");

    public String name;

    Singleton(String name) {
        this.name=name;
    }

    public static void main(String[] args) {
        System.out.println(SINGLETON.name);
    }
}

 

饿汉单例模式:

在类加载时就初始化实例,不能修改,无法防御反射和序列化攻击。

public class StavingSingleton {
    private static final StavingSingleton stavingSingleton = new StavingSingleton();

    private StavingSingleton(){}

    public static StavingSingleton getInstance(){return stavingSingleton;}

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        System.out.println(StavingSingleton.getInstance());
        System.out.println(StavingSingleton.getInstance());
        //反射攻击
        Class stavingSingletonClass = StavingSingleton.class;
        Constructor constructor = stavingSingletonClass.getDeclaredConstructor();
        //破除private的防御
        constructor.setAccessible(true);
        System.out.println(constructor.newInstance());
    }

}

 

懒汉单例模式:

在需要时才初始化实例,可以被其他线程修改,无法防御反射和序列化攻击。

第二步初始化对象和第三步在没有volatile 关键字的时候是可以被程序任意调整的,由于第二步有时耗时比较长,有可能会返回还没有初始化好的实例,加上volatile 关键字后程序会严格按照1、2、3步骤执行。 

public class LazySingleton {

    private volatile static LazySingleton lazySingleton;

    private LazySingleton(){}

    public static LazySingleton getInstance(){
        if(lazySingleton == null){
            //同步
            synchronized (LazySingleton.class){
                if(lazySingleton == null){
                    //memory = allocate();       1、分配内存空间
                    //instance(memory)           2、初始化对象
                    //lazySingleton = memory;   3、设置lazySingleton指向刚分配的内存地址,此时lazySingleton != null
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        System.out.println(LazySingleton.getInstance());
        System.out.println(LazySingleton.getInstance());
        Class lazySingletonClass = LazySingleton.class;
        Constructor constructor = lazySingletonClass.getDeclaredConstructor();
        constructor.setAccessible(true);
        System.out.println(constructor.newInstance());
    }
}

 

https://www.cnblogs.com/andy-zhou/p/5363585.html#_caption_3

https://www.cnblogs.com/hxsyl/archive/2013/03/19/2969489.html

posted on 2018-11-30 21:36  袁子弹  阅读(136)  评论(0编辑  收藏  举报