小白都能懂的设计模式 java版 单例模式

单例模式是每个程序员都很清楚的设计模式
这里先介绍三种,饿汉式单例,懒汉式单例,静态内部类,直接code,比较清晰~

饿汉式单例:

package shejimoshi;

//饿汉式单例
public class HungrySingle {
    //可能会浪费空间
    private byte[] data1 = new byte[2024*2024];
    private byte[] data2 = new byte[2024*2024];
    private byte[] data3 = new byte[2024*2024];
    private byte[] data4 = new byte[2024*2024];

    private HungrySingle(){

    }
    private final static HungrySingle HUNGRY_SINGLE = new HungrySingle();

    public static HungrySingle getInstance() {
        return HUNGRY_SINGLE;
    }
}

懒汉式单例:

package shejimoshi;

//懒汉式单例
public class LazyMan {
    private LazyMan() {
        System.out.println(Thread.currentThread().getName() + "ok");
    }
    private volatile static LazyMan lazyMan;

    //双重检测锁模式的 懒汉式单例 DCL 懒汉式
    public static LazyMan getInstance() {
        if(lazyMan == null) {
            synchronized (LazyMan.class) {
                if (lazyMan == null) {
                    lazyMan = new LazyMan();    //不是一个原子性操作
                    /*
                    * 1. 分布内存空间
                    * 2. 执行构造方法,初始化对象
                    * 3. 把整个对象指向整个空间
                    *
                    * 123执行顺序可能是132,可能有问题,
                    * */
                }
            }
        }
        return lazyMan;
    }

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

使用静态内部类:

package shejimoshi;

//静态内部类
public class Holder {
    private Holder() {

    }

    public static Holder getInstance() {
        return InnerClass.HOLDER;
    }

    public static class InnerClass {
        private static final Holder HOLDER = new Holder();
    }
}

反射可以通过setAccessible = true,破坏单例模式的私有性,所以上述都是不安全的

public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        LazyMan instance1 = LazyMan.getInstance();
        Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
        //破坏构造器私有性
        declaredConstructor.setAccessible(true);
        LazyMan instance2 = declaredConstructor.newInstance();

        System.out.println("instance1 = " + instance1);
        System.out.println("instance2 = " + instance2);

    }

在这里插入图片描述
解决方式后续补充~

猜你喜欢

转载自blog.csdn.net/weixin_45806131/article/details/108397015