[DesignPattern] 设计模式 -- 单例(Singleton)

Design Pattern : Singleton (设计模式:单例)

单例模式(Singleton):单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。

几种实现方法:
方法一: 这种方法很简单,就是把instance变成private,构造方法也是如此,用getInstance来得到引用。这样做线程安全,但在没有使用的时候就要初始化,比较耗费资源。

public class Mgr01 {
    private static final Mgr01 INSTANCE = new Mgr01();
    private Mgr01() {}
    public static Mgr01 getInstance() {
        return INSTANCE;
    }
}

方法二: 这种方法是在使用该单例的时候才初始化。为了保证线程安全,给getInstance上锁。但是因为整个method都上锁,所以每次调用该单例都要加锁。比较耗费资源。

public class Mgr02 {
    private static Mgr02 INSTANCE;
    private Mgr02() {}
    public static synchronized Mgr02 getInstance() {
        if (INSTANCE == null) {   
            INSTANCE = new Mgr02();
        }
        return INSTANCE;
    }
}

方法三: 这是在方法二的基础上做的改进版。在这个版本中,我们只有在第一次INSTANCE还是null的时候才加锁,改善效率。需要注意的是为了保证线程安全,需要两次检查是不是为null。所以相对比较繁琐。

public class Mgr03 {
    private static volatile Mgr03 INSTANCE;
    private Mgr03() {}
    public static Mgr03 getInstance() {
        if (INSTANCE == null) {
            synchronized(Mgr03.class) {
                if (INSTANCE == null) {

                    INSTANCE = new Mgr03();
                }
            }
        }
        return INSTANCE;
    }
}

方法四: 静态内部类。因为外部类加载的时候内部类不加载,静态内部类只有在使用的时候才会被加载,所以同样可以避免未使用就创建的尴尬。线程安全。

public class Mgr04 {
    private Mgr04() {}
    private static class Mgr04Holder{
        private static Mgr04 INSTANCE = new Mgr04();
    }
    public static Mgr04 getInstance() {
        return Mgr04Holder.INSTANCE;
    }
}

方法五:把class变成enum。这样不但是可以实现使用时候创建,线程安全,还可以防止反序列化。Effective java中推荐使用。因为一般的Java的反射可以通过一个class文件,把class文件加载到内存再把它new一个实例出来。但枚举类文件没有构造方法。

public enum Mgr05 {
    INSTANCE;
    public Mgr05 getInstance() {
        return INSTANCE;
    }

}

一个比较全面的link做参考

posted on 2020-06-04 11:49  codingEskimo  阅读(127)  评论(0编辑  收藏  举报

导航