Java——单例模式

一、概述

单例模式,是一种常用的软件设计模式,通过单例模式,可以保证系统中,应用该模式的这个类只有一个实例,就是说,一个类只有一个对象实例。

二、引用场景和好处

  • 应用场景:当程序汇总某个类仅允许创建一个对象,供外部使用时,可以使用单例模式
  • 好处:永远保证只有一个对象

三、实现步骤

单例模式的实现步骤分为以下3步

  1. 将构造方法私有化,使其不能在类的外部通过 new 关键字实例化该类对象
  2. 在该类内部产生一个唯一的实例化对象,并且将其封装为 private static 类型的成员变量
  3. 定义一个静态方法返回这个唯一对象

四、单例模式分类

根据实例化对象的时机,单例设计模式又分为以下2种

  1. 饿汉单例设计模式
  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;
    }
}

  

  

原文地址:https://www.cnblogs.com/xulinjun/p/15091259.html