java设计模式---单例模式(Singleton)

前言

在接下来的时间,每周都会给大家分享一个设计模式,欢迎大家关注、留言。

源码地址(欢迎star)

设计模式是什么?为什么要学习设计模式?

设计模式是程序员在设计应用程序或系统时可以用来解决常见问题的最佳做法。
设计模式可以通过提供经过验证的开发范例来加快开发过程。
重用设计模式有助于防止可能导致重大问题的微妙问题,并且还提高了熟悉模式的编码人员和架构师的代码可读性。

1. 枚举(推荐)

public enum EnumSingleton {
    INSTANCE;

    @Override
    public String toString() {
        return getDeclaringClass().getCanonicalName() + "@" + hashCode();
    }
}

这种方式是Effective Java作者Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。由于1.5中才加入enum特性,使用时要注意。

2. 静态内部类(推荐)

public class StaticInnerClassSingleton {

    private StaticInnerClassSingleton() {
    }


    public static StaticInnerClassSingleton getInstance() {
        return HelperHolder.INSTANCE;
    }

    private static class HelperHolder {
        private static final StaticInnerClassSingleton INSTANCE =
                new StaticInnerClassSingleton();
    }
}

这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,当Singleton类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。如果实例化instance很消耗资源,我想让他延迟加载。所以我认为该方式要优于下面的将要提到的饿汉和懒汉模式。

3. 饿汉

public class EagerSingleton {
    public static final EagerSingleton INSTANCE = new EagerSingleton();

    private EagerSingleton() {
        
    }
}

4. 饿汉(升级)

public class EagerPlusSingleton {
    private static EagerPlusSingleton INSTANCE = null;

    static {
        INSTANCE = new EagerPlusSingleton();
    }

    private EagerPlusSingleton() {
    }

    public static EagerPlusSingleton getInstance() {
        return INSTANCE;
    }

}

5. 懒汉

public class LazySingleton {
    private static LazySingleton INSTANCE = null;

    private LazySingleton() {
    }

    public static synchronized LazySingleton getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new LazySingleton();
        }
        return INSTANCE;
    }
}

6. 懒汉(升级)

public class LazyPlusSingleton {

    private volatile static LazyPlusSingleton INSTANCE;

    private LazyPlusSingleton() {
    }

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

总结

  1. 除了枚举,其他方式都可以通过反射得到多个实例。所以我建议:如果项目依赖jdk1.5以上,可以考虑切换到枚举实现的单例,其他建议使用静态内部类。
  2. 单例模式不能滥用,在做安卓开发的过程中如果遇到单例模式的代码中有Context, 且Context不是Application的。这是就要留意这个单例是否必要。如果确实需要使用单例,建议使用Application作为参数,避免内存泄露。

单例模式网上有很多,我也借鉴了网上的资源,达到巩固和加深理解的作用。

更多内容可以关注我的公众号或者搜索SamuelAndroid关注我:

java设计模式---单例模式(Singleton)_第1张图片
公众号

你可能感兴趣的:(java设计模式---单例模式(Singleton))