设计模式1,单例模式

1:类的加载顺序

先执行父类的静态代码块和静态变量初始化,静态代码块和静态变量的执行顺序跟代码中出现的顺序有关。
执行子类的静态代码块和静态变量初始化。
执行父类的实例变量初始化
执行父类的构造函数
执行子类的实例变量初始化
执行子类的构造函数

2:单例模式:饿汉式

/**
 * 单例模式:饿汉式
 *          类加载的时候就完成了实例化
 *      优点:没有线程的安全的问题
 *      缺点:类的实例没有使用的时候就会创建,占用内存
 */
public class SingleModel1 {
    private SingleModel1() {}
    private final static SingleModel1 INSTANCE = new SingleModel1();
    public static SingleModel1 getInstance() {
        return INSTANCE;
    }
}

3:单例模式:懒汉式1

/**
 * 单例模式:懒汉式加载
 * 获取实例的时候才会创建对象
 * 优点:解决了对象过早的实例化问题,避免内存浪费
 * 缺点:每次获取实例化的时候因为synchronized产生性能问题
 */
public class SingleModel2 {

    //volatile关键字:保证内存的可见性;避免了指令重排问题,造成实例化未结束的时候,其他线程调用getInstance方法造成的实例的INSTANCE是不完全的,从而造成空指针异常
    private volatile static SingleModel2 INSTANCE = null;

    private SingleModel2() {
    }

    public synchronized SingleModel2 getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new SingleModel2();
        }
        return SingleModel2.INSTANCE;
    }

}

4:单例模式:懒汉式2

/**
 * 单例模式:懒汉式加载
 *   双重检查懒汉式
 */
public class SingleModel3 {

    private static volatile SingleModel3 INSTANCE = null;

    private SingleModel3() {
    }

    public static SingleModel3 getInstance() {

        if (SingleModel3.INSTANCE == null) {
            synchronized (SingleModel3.class) { //锁的位置不同,减少性能的浪费
                INSTANCE = new SingleModel3();
            }
        }
        return INSTANCE;
    }
}

5:静态内部类 (推荐)

/**
 * 静态内部类模式
 */
public class SingleModel4 {

    private static class InstanceHolder {
        private final static SingleModel4 singleModel4 = new SingleModel4();
    }

    public SingleModel4 getInstance() {
        return InstanceHolder.singleModel4;
    }

}

6:枚举方式(推荐)

 /**
 * 枚举方式
 */
public class SingleModel5 {
    private SingleModel5() {
    }

    public enum InstanceEnum {
        INSTANCE;
        private final SingleModel5 instance;

        InstanceEnum() {
            instance = new SingleModel5();
        }
    }

    public SingleModel5 getInstance() {
        return InstanceEnum.INSTANCE.instance;
    }
}

7: 举例

单例的线程池

/**
 * @Auther: ZhangSuchao
 * @Date: 2020/6/9 17:36
 */
public class SingleThreadPool {

    private static class ThreadPoolHolder {
        private static ThreadPoolExecutor pool = new ThreadPoolExecutor(20, 200, 60L, TimeUnit.SECONDS, new SynchronousQueue());
    }

    public static ThreadPoolExecutor getInstance() {
        return ThreadPoolHolder.pool;
    }
}

直接通过

SingleThreadPool.getInstance() 获取线程池实例

备注

也可以通过ioc容器管理,标记成单例模式(更简单),理论上ioc管理的单例,不是真正的单例,因为控制不了其他人员使用new的方式创建

猜你喜欢

转载自blog.csdn.net/Draymond_feng/article/details/107693191
今日推荐