一、概述
单例模式,是一种常用的软件设计模式,通过单例模式,可以保证系统中,应用该模式的这个类只有一个实例,就是说,一个类只有一个对象实例。
二、引用场景和好处
- 应用场景:当程序汇总某个类仅允许创建一个对象,供外部使用时,可以使用单例模式
- 好处:永远保证只有一个对象
三、实现步骤
单例模式的实现步骤分为以下3步
- 将构造方法私有化,使其不能在类的外部通过 new 关键字实例化该类对象
- 在该类内部产生一个唯一的实例化对象,并且将其封装为 private static 类型的成员变量
- 定义一个静态方法返回这个唯一对象
四、单例模式分类
根据实例化对象的时机,单例设计模式又分为以下2种
- 饿汉单例设计模式
- 懒汉单例设计模式
五、饿汉单例设计模式
4.1、概述
饿汉单例设计模式就是随着类的加载的时候已经将对象创建完毕,不管以后会不会使用到该实例对象,先创建了再说。
4.2、实现格式
比如这里定义一个皇帝类
public class King { // 构造方法私有化 private King() { } // 当前类内部实例化一个本类对象 private static final King king = new King(); // 直接初始化(不考虑是否使用) // 对外提供一个静态方法:让外部可以获取到King的实例对象 public static King getInstance(){ return king; } }
在测试类中进行测试
public class TestSing { @Test public void test01(){ King k1 = King.getInstance(); System.out.println(k1); // com.itheima.sh.King@2fd66ad3 King k2 = King.getInstance(); System.out.println(k2); // com.itheima.sh.King@2fd66ad3 } }
通过测试可以发现,实例化出来的k1、k2对象的地址值一致。也就是同一个对象实例。
六、懒汉单例设计模式
5.1、基本概述
懒汉单例设计模式就是调用 getInstance() 方法时实例对象才被创建,先不急着实例化出对象,而是等要用的时候才实例化出对象。
5.2、实现格式
public class King2 { // 构造方法私有化 private King2(){ } // 定义本类的成员变量 private static King2 king2; // 不需要初始化 // 静态方法 public static King2 getInstance(){ // 判断king2是否为null if(king2 == null){ king2 = new King2(); } return king2; } }
在测试类中进行测试
public class TestSing { @Test public void test02(){ King2 k1 = King2.getInstance(); King2 k2 = King2.getInstance(); System.out.println(k1); // com.itheima.sh.King2@2fd66ad3 System.out.println(k2); // com.itheima.sh.King2@2fd66ad3 } }
2个对象实例打印出来的地址值也是一致的。
5.3、懒汉单例设计模式在多线程开发中的注意事项
懒汉单例设计模式在多线程环境下可能会实例化出多个对象,不能保证单例的状态,所以需要加上关键字 synchronized,保证其同步安全。如下
public class King2 { // 构造方法私有化 private King2(){ } // 定义本类的成员变量 private static King2 king2; // 不需要初始化 // 静态方法 public static synchronized King2 getInstance(){ // 判断king2是否为null if(king2 == null){ king2 = new King2(); } return king2; } }