单例模式

单例模式

不要new对象

饿汉式单例,线程安全,浪费资源

public class Hungry {
    //浪费空间
    private byte[] data1 = new byte[1024*1024];
    private byte[] data2 = new byte[1024*1024];
    private byte[] data3 = new byte[1024*1024];
    private byte[] data4 = new byte[1024*1024];

    private Hungry(){

    }
    private final static Hungry HUNGRY = new Hungry();

    public static Hungry getHUNGRY() {
        return HUNGRY;
    }
}

双重检测懒汉式单例。创建实例时,不加同步线程不安全,加了效率不高

public class LazyMan {
    private LazyMan(){
        System.out.println(Thread.currentThread().getName()+"ok");
    }

    private volatile static LazyMan lazyMan;

    //  volatile和if (lazyMan==null)双重检测锁模式的 懒汉式单例 DCL懒汉式
    public static LazyMan getLazyMan() {
        if (lazyMan==null){
            lazyMan =new LazyMan();//不是原子性操作
            /*
            1.分配内存空间
            2.执行构造方法
            3.把这个对象指向这个空间
            123
            可能发生指令重排导致
            132 A
                B此时lazyMan没有完成构造
             */
        }

        return lazyMan;
    }
//多线程并发测试
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                LazyMan.getLazyMan();
            }).start();
        }
    }
}

静态内部类式

public class OuterClass {
    private OuterClass(){
        System.out.println(Thread.currentThread().getName()+" ok");
    }
    public static OuterClass getInstance(){
        return InnerClass.OUTER_CLASS;
    }

    public static class InnerClass{
        private static final OuterClass OUTER_CLASS=new OuterClass();
    }
}

枚举类型构造单例

public enum EnumSingle {
    INSTANCE;

    public EnumSingle getInstance(){
        return INSTANCE;
    }
}
class Test{
    public static void main(String[] args) throws Exception{
//        EnumSingle enumSingle=EnumSingle.INSTANCE;
        Constructor<EnumSingle> declaredConstructor= EnumSingle.class.getDeclaredConstructor(String.class,int.class);
        declaredConstructor.setAccessible(true);

        EnumSingle enumSingle1=declaredConstructor.newInstance();
        EnumSingle enumSingle2=declaredConstructor.newInstance();


    }
}

破坏单例

使用反射破坏单例

    public static void main(String[] args) throws Exception {
//        LazyMan lazyMan = LazyMan.getLazyMan();
        Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
        declaredConstructor.setAccessible(true);
        LazyMan lazyMan1 =declaredConstructor.newInstance();
        LazyMan lazyMan2 = declaredConstructor.newInstance();

        System.out.println(lazyMan1);
        System.out.println(lazyMan2);
    }
posted @ 2021-01-28 17:21  tanjr  阅读(80)  评论(0编辑  收藏  举报