这个教程写的真好:https://blog.csdn.net/mnb65482/article/details/80458571
1. 什么是单例模式?
单例模式确保某个类只有一个实例。
单例类必须自己创建自己的唯一实例。
单例类要给其他对象提供这一个实例。
2. 为什么需要单例模式?
保证了一个类仅有一个实例,并且其他类都能够访问到这个实例。
避免了一个全局访问的类频繁的创建与销毁。
3.单例模式的几种创建方法?
1)饿汉式(立即加载)
public class T{ private static T sInstancs = new T(); private T(){ } public static T getInstance(){ return sInstancs; } }
饿汉式单例在类加载初始化时就创建好一个静态的对象供外部使用,除非系统重启,这个对象不会改变,所以本身就是线程安全的。
2)懒汉式(延迟加载)
public class T{ private static T sInstancs = null; private T(){ } public static T getInstance(){ if(sInstancs == null){ sInstancs = new T(); } return sInstancs; } }
实现了延迟加载,但是在多线程环境下会产生多个单例对象。
3)双重检验(Double Check Lock)
public class T{ private static T sInstancs = null; private T(){ } public static T getInstance(){ if(sInstancs == null){ synchronized (T.class) { if(sInstancs == null) { sInstancs = new T(); } } } return sInstancs; } }
保证了线程安全,也比锁住整个方法效率更高。
4)静态内部类
public class T{ private T(){ } private static class InstanceHolder{
//这个instance是private的 说明只能在这个内部类中使用,为什么getInstance()可以调用? private static T instance = new T(); } public static T getInstance(){ return InstanceHolder.instance; } }
保证线程安全,也能保证单例的唯一性,也能延迟单例的实例化。静态内部类也有着一个致命的缺点,就是传参的问题,由于是静态内部类的形式去创建单例的,故外部无法传递参数进去。
所以,我们创建单例时,可以在静态内部类与DCL模式里自己斟酌。