单例模式(Singleton)保证一个类仅有一个实例,并提供一个访问它的全局访问点。简单来说就是对类实现计划生育,控制它实例的数量。
单例模式的实现有六种:
1、线程不安全的懒汉式,这种方式是最基础的实现方式之一,最大的弊端是线程不安全,造成不安全的主要因素是方法没有加锁synchronized,在数据量大且线程不安全的场景不建议使用。
2、线程安全的懒汉式,顾名思义,懒汉式,在第一次被调用的时候进行初始化,没有人调用就不进行初始化,但是是线程安全,可以在多线程下使用。
3、饿汉式,顾名思义,饿汉会卖你对资源的时候会想着先存储大量的资源,程序也是如此,饿汉式会类加载时就初始化,浪费内存,造成资源浪费。
4、双检索/双重校验锁 对实例加锁机制进行双重的条件判断,检验满足加锁的条件才加锁,避免了无效的加锁浪费内存,造成资源浪费。这种方式是在懒汉式和饿汉式的基础上进行加固。
5、登记式/静态内部类 这种方式是简化了双检索的实现,但是达到了双检索同等的功效,利用了JAVA中类加载机制确保类初始化的时候只有一个实例。
6、枚举 这个没有被广泛推广但是是单例模式的最佳实现的模式,支持JAVA中序列化,更细粒度的控制类被多次实例化。因为是JDK1.5之后才有了枚举的特性,所以这种类型的单例模式没有得到很好的推广。
总结来说:虽然这几种都能实现单例模式,但是我们在使用过程中根据不同的场景,要有所选择性,通常来说,第一种和第二种懒汉式都不建议使用,建议使用第三种饿汉式。在明确LAZYLOADING 模式下,我们选用第五种登记模式。如果创建对象涉及到序列化,强烈建议使用第六种枚举。对于其他特殊需求,第四种双重锁可以考虑考虑。