单例模式:作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
特点:
- 单例类只能有一个实例
- 单例类必须自己创建自己的唯一实例
- 单例类必须给所有其他对象提供这一实例
饿汉式单例类:
特点:典型的空间换时间,不管你用不用都会创建出一个实例
package singleton; /** * 饿汉式单例:典型的空间换时间,不管你用不用都会创建出一个实例 */ public class EagerSingleton { private static EagerSingleton instance = new EagerSingleton(); /** * 构建私有的构造器 */ private EagerSingleton(){ } /** * 静态工厂方法 * @return */ public static EagerSingleton getInstance(){ return instance; } }
懒汉式单例类:
特点:典型的时间换空间,需要用到的时候 再创建对象;
package singleton; /** * 懒汉单例:典型的时间换空间,需要用到的时候 再创建对象; * 虽然它是线程安全的,但是会降低整个访问的速度,而且每次都要判断。 */ public class LazySingleton { private static LazySingleton instance = null; private LazySingleton(){ } public static synchronized LazySingleton getInstance(){ if (instance == null) { instance = new LazySingleton(); } return instance; } }
双重检查加锁类:
特点:即实现线程安全,又能够时性能不受很大的影响;
第一重检查:并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法后,先检查实例是否存在,如果不存在才进行下面的同步块;
第二重检查:进入同步块过后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例;
package singleton; /** * 双重检查枷锁:即实现线程安全,又能够时性能不受很大的影响; * 第一重检查:并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法后,先检查实例是否存在,如果不存在才进行下面的同步块; * 第二重检查:进入同步块过后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例; * */ public class Singleton { //被volatile修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能够正确的处理该变量。 //注意:在Java1.4及以前版本中,很多jvm对于volatile关键字的实现的问题,会导致“双重检查加锁”的失败,因此“双重检查加锁”机制只能用在java5及以上的版本。 private static volatile Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ //先检查实例是否存在,如果不存在才进入下面的同步代码块 if (instance == null) { //同步块,线程安全的创建实例 synchronized (Singleton.class) { //再次检查实例是否存在,如果不存在才真正的创建实例 if (instance == null) { instance = new Singleton(); } } } return instance; } }
懒加载内部实现:
特点:实现了延迟加载和线程安全
package singleton; public class Singleton { private Singleton(){} /** * 类及的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例没有绑定关系, * 而且只有被调用到时才会装载,从而实现了延迟加载。 */ private static class SingletonHolder{ /** * 静态初始化器,由JVM来保证线程安全 */ private static Singleton instance = new Singleton(); } public static Singleton getInstance(){ return SingletonHolder.instance; } }
枚举单例类:
特点:
简单、无偿的提供了序列化机制,并由JVM根本上提供保障,绝对防止多次实例化,是更简洁、高效、安全的实现单例的方式。
public enum Singleton { /** * 定义一个枚举的元素,它就代表了Singleton的一个实例。 */ uniqueInstance; /** * 单例可以有自己的操作 */ public void singletonOperation(){ //功能处理 } }