单例模式的几种实现

2019-11-21  本文已影响0人  缓慢移动的蜗牛

单例的定义

定义:一个类只有一个实例,而且自行实例化并向整个系统提供整个实例。

单例模式的应用

单例模式的优点

由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁的创建、销毁时,而且创建或销毁时性能又无法优化,单例模式的优势就非常明显。
由于单例模式只生成一个实例,所以减少了系统的性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后用永久驻留内存的方方式来解决。
单例模式可以避免对资源的多重占用,例如一个写文件动作,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。
单例模式可以在系统设置全局访问点,优化和共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理。

单例模式的缺点

单例模式一般没有接口,扩展很困难,若要扩展,除了修改代码基本上没有第二种途径可以实现。单例模式为什么不能增加接口?因为接口对单例模式没有任何意义 ,它要求“自行实例化”,并且提供单一实例,接口或抽象类是不可能实例化的。当然,在特殊情况下,单例模式可以实现接口、被继承、需要在系统开发中根据环境判断。

单例模式的几种实现

饿汉式

public class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton(){}

    public static Singleton getInstance(){
        /**
         * 此版本的缺点是:该方法中不能有其他实例变量,
         * 因为getInstance()方法没有同步,所以会出现非线程安全问题
         */
        return instance;
    }

}

懒汉式, 使用DCL双重检测锁机制

public class Singleton {
    private volatile static Singleton instance;
    private Singleton(){}

    /**
     * 使用双重检测机制来解决问题,既保证了不需要同步代码的异步执行性,有保证了单例的效果
     * @return
     */
    public static Singleton getInstance(){
        try{
            if (instance != null) {
            }else{
                synchronized (Singleton.class){
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return instance;
    }
}

static代码块

public class Singleton {
    private static Singleton instance = null;

    private Singleton(){}

    static {
        instance = new Singleton();
    }

    public static Singleton getInstance(){
        return instance;
    }
}

枚举模式的单例类

public class EnumSingleton {
    private EnumSingleton(){}
    public static EnumSingleton getInstance(){
        return Singleton.INSTANCE.getInstance();
    }


    private enum Singleton{
        INSTANCE;
        private EnumSingleton singleton;

        /**
         * 枚举enum和静态代码块的特性相似,在使用枚举类时,构造方法会被自动调用
         * JVM保证此方法只会被调用一次
         */
        Singleton(){
            singleton = new EnumSingleton();
        }
        public EnumSingleton getInstance(){
            return singleton;
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读