概述
单例设计模式 : 确保一个类只能有一个实例,并提供一个全局访问点来访问这个实例. (Singleton Pattern : Ensure a class has only one intance,and provide a global point of access to it. ). 单例设计模式是一种对象创建型模式,其主要有三个要点 :
- 某个类只能有一个实例
- 必须自行创建这个实例
- 必须自行向系统提供这个实例
示例程序-饿汉式单例
饿汉式单例类( Eager Singleton )是最简单的单例类,既类被加载时静态变量 instance 就会被初始化,程序示例如下所示 :
/** * 功能描述:单例模式-饿汉式单例 * * @author lihao * @create 2019-11-01 23:47 */ public class Singleton { private static Singleton singleton = new Singleton(); private Singleton() { System.out.println("生成了一个实例"); } public static Singleton getInstance() { return singleton; } }
注:从资源利用效率的角度来讲饿汉式单例不及懒汉式单例,而且系统加载时由于需要创建饿汉式单例对象,加载时间可能比较长
示例程序-懒汉式单例
与饿汉式单例不同的是,懒汉式单例类( Lazy Singleton )在第一次被引用时才会将自己实例化,当单例类被加载时并不会将自己实例化, 示例程序如下所示 :
/** * 功能描述:单例模式-懒汉式单例 * * @author lihao * @create 2019-11-02 0:00 */ public class LazySingleton { private volatile static LazySingleton instance = null; private LazySingleton() { System.out.println("生成了一个实例"); } public static LazySingleton getInstance() { if (instance == null) { synchronized (LazySingleton.class) { if (instance == null) { instance = new LazySingleton(); } } } return instance; } }
注:由于volatile关键字会屏蔽Java虚拟机所做的一切代码优化,继而可能会导致系统的运行效率降低,因此即使使用双重检查锁定来实现单例模式也不是一种完美的实现方法
示例程序-内部类单例
饿汉式单例不能实现延迟加载,不管将来用不用始终占据内存. 懒汉式单例类线程安全控制繁琐,而且性能受影响. 为了克服这些问题,在Java语言中可以通过使用 Initialization on Demand Holder( IoDH )技术来实现单例模式,示例程序如下所示 :
/** * 功能描述:单例模式-内部类 * * @author lihao * @create 2019-11-02 0:07 */ public class InnerClassSingleton { private InnerClassSingleton() { } public static class InnerClass { private final static InnerClassSingleton instance = new InnerClassSingleton(); } public static InnerClassSingleton getInstance() { return InnerClass.instance;H } }
注 : 通过使用IoDH既可以实现延迟加载,又可以保证线程安全,不影响系统性能,既其为一种最好的Java语言单例模式实现方式,其缺点为很多面向对象语言并不支持IoDH