一、什么是单例模式:
单例模式是一种确保了一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。被实例化的类称为单例类。
二、单例模式的特点:
- 单例类只有一个实例。
- 单例类必须自行创建自己唯一的实例。
- 单例类必须给其他对象提供这个实例。
注意:虽然单例模式和单例类限定了只能有一个实例,但是作为单例模式的推广,可以推广到任意且有限多个实例的情况,这时候被称为多例模式和多例类。
三、单例模式的结构:
- 一个单例类只有一个实例。
- 单例类的实例持有对自己的引用。
四、单例模式的实例化:
Java中单例模式有着自己的特点,具体表现在单例类的实例化上:
饿汉式单例类:
Java中最简单的单例类,类的单例被声明为静态变量,在类加载时,调用类的私有构造函数,静态变量被实例化。
特点:类的构造函数私有,避免了外界利用构造函数创建任意多的实例。且由于构造函数私有,类不能被继承。
1 /** 2 * @author ZhouDX 3 * @since 2019/3/4 22:12:28 4 */ 5 public class HungerSingleton { 6 private static final HungerSingleton HUNGER_SINGLETON = new HungerSingleton(); 7 8 /** 9 * 私有的默认构造函数 10 */ 11 private HungerSingleton() { 12 } 13 14 /** 15 * 静态工厂方法 16 */ 17 public static HungerSingleton getInstance() { 18 return HUNGER_SINGLETON; 19 } 20 }
汉懒式单例类:
与饿汉式单例类相同的是构造函数私有;不同之处在于懒汉式单例类在第一次被引用时将自己实例化,如果加载器是静态的,懒汉式单例类被加载时不会将自己实例化。
使用了synchronized对静态工厂类方法进行了同步,已处理多线程的问题
1 /** 2 * @author ZhouDX 3 * @since 2019/3/4 22:23:02 4 */ 5 public class LazySingleton { 6 private LazySingleton lazySingleton = null; 7 8 /** 9 * 构造函数 10 */ 11 private LazySingleton() { 12 } 13 14 /** 15 * 静态工厂方法,返回懒汉式实力类的唯一实例 16 * 17 * @return 18 */ 19 synchronized public LazySingleton getInstance() { 20 if (lazySingleton == null) { 21 return lazySingleton = new LazySingleton(); 22 } 23 return lazySingleton; 24 } 25 26 }
懒汉式单例类与饿汉式单例类的比较:
- 饿汉式单例类在自己被加载时将自己实例化,即便加载器是静态的,依旧在加载时实例化自己;懒汉式单例类在第一次被引用时将自己实例化,如果加载器是静态的,懒汉式单例类被加载时不会将自己实例化。
- 从资源利用角度讲,懒汉式单例类的资源利用效率高点;从速度和反应时间来讲,饿汉式的好点。