Java 单例模式 (Singleton Pattern)

2019-12-27  本文已影响0人  Mrs_MR

分享两个典型的Java单例模式写法:

第一种: 双检锁机制实现单例模式 -- 较复杂,且无法避免使用反射和反序列化的方式来获得该实例;

第二种: 使用枚举来实现单例模式 -- 代码简单, 可以解决反射/反序列化获取实例的问题, 另外其本身也是线程安全的;

第一种方式代码:

/**
 *
 * 单例模式:Singleton Pattern
 * 主要解决:一个全局使用的类频繁地创建与销毁。
 * 何时使用:当您想控制实例数目,节省系统资源的时候。
 * 如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
 * 关键代码:构造函数是私有的。
 *
 * 本例使用:
 * 双检锁/双重校验锁(DCL, 即 double-checked locking)
 *
 * @author MY
 * @date 2019/12/3
 */
public class SingleObject {

    /**
     * 创建实例
     * 使用 volatile 关键字, 禁止重排序, 使所有的write操作都发生在read操作之前
     * */
    public static volatile  SingleObject instance;

    /** 将构造函数私有化 */
    private SingleObject(){}

    /** 获取实例 */
    public static SingleObject getInstance(){
        if(instance == null){
            synchronized (SingleObject.class){
                // 再次判空, 防止多个线程同时通过第一步判空操作
                if(instance == null){
                    instance = new SingleObject();
                }
            }
        }
        return instance;
    }
}

第二种方式代码:

/**
 * 使用单元素枚举(enum)来实现单例模式
 *
 * @author MY
 * @date 2019/12/30.
 */
public enum EnumSingleObject {

    INSTANCE;

    private Object instance;

    EnumSingleObject(){
        //todo: 在此处可以对instance做初始化操作
    }

    public EnumSingleObject getInstance(){
        return INSTANCE;
    }

}

第二种方法-实例:

import java.util.concurrent.*;

/**
 * @author MY
 * @date 2019/12/30.
 */
public class LocalThreadPoolExecutors {

    enum EnumThreadPoolExecutor{

        INSTANCE;

        /** ThreadPoolExecutor */
        private ThreadPoolExecutor threadPoolExecutor;

        EnumThreadPoolExecutor(){
            threadPoolExecutor = new ThreadPoolExecutor(5,
                    20 ,
                    10,
                    TimeUnit.SECONDS,
                    new LinkedBlockingQueue(128),
                    new ThreadPoolExecutor.CallerRunsPolicy()
            );
        }

        /**
         * @return
         */
        public ThreadPoolExecutor getInstance(){
            return threadPoolExecutor;
        }
    }

    public static void main(String[] args){
        EnumThreadPoolExecutor.INSTANCE.getInstance();
        ThreadPoolExecutor threadPoolExecutor = EnumThreadPoolExecutor.INSTANCE.getInstance();
    }
}
上一篇下一篇

猜你喜欢

热点阅读