设计模式1,单例模式

类的加载顺序

  • 先执行父类的静态代码块和静态变量初始化,静态代码块和静态变量的执行顺序跟代码中出现的顺序有关。
  • 执行子类的静态代码块和静态变量初始化。
  • 执行父类的实例变量初始化
  • 执行父类的构造函数
  • 执行子类的实例变量初始化
  • 执行子类的构造函数
单例模式:饿汉式
/**
 * 单例模式:饿汉式
 *          类加载的时候就完成了实例化
 *      优点:没有线程的安全的问题
 *      缺点:类的实例没有使用的时候就会创建,占用内存
 */
public class SingleModel1 {
    private SingleModel1() {}
    private final static SingleModel1 INSTANCE = new SingleModel1();
    public static SingleModel1 getInstance() {
        return INSTANCE;
    }
}
单例模式:懒汉式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;
    }

}
单例模式:懒汉式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; } }

静态内部类 (推荐)

 

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

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

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

}

 

枚举方式(推荐)

 

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

    public enum InstanceEnum {
        INSTANCE;
        private final SingleModel5 instance;

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

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

 

 
举例:
  
单例的线程池

/**
 * @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的方式创建
 
 
posted @ 2020-02-17 20:53  Draymond  阅读(148)  评论(0编辑  收藏  举报