Java零基础入门笔记11-Java单例模式

1、概述

  • 设计模式Design Pattern)是一套被反复使用多数人知晓的经过分类的代码设计经验的总结(引自百科)。简单来说就是,设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案
  • 详细的设计模式的讲解请参考菜鸟教程:设计模式
  • 设计模式不是基于理论发明的,相反,它是基于具体的需求逐渐演化形成的解决方案。因此在学习设计模式的时候,最好结合实际场景中的问题来理解和分析

2、单例模式

  • 定义:一个类有且仅有一个实例,并且自行实例化向整个系统提供。
  • 目的:使得类的一个对象成为该类系统中的唯一实例。
  • 要求:
    1. 某个类只能有一个实例
    2. 必须自行创建实例
    3. 必须自行向整个系统提供这个实例
  • 实现的方法:
    1. 只提供私有的构造方法
    2. 含有一个该类的静态私有对象
    3. 提供一个静态的公有的方法用于创建、获取静态私有对象。
  • 实现方案:
    • 饿汉式:对象创建过程中实例化(创建对象实例的时候直接初始化)。
    • 懒汉式:对象创建时并不实例化,而是在静态公有方法中实例化(用到的时候才去实例化)。

3、饿汉模式VS懒汉模式

新建一个名为Singleton的Java项目,新建两个包,分别为:com.cxs.singletoncom.cxs.test,并在test包下新建一个测试类Test用于测试。

3.1、饿汉式的代码实现

  • 1.在singleton包下新建一个名为Hunger的类,代码如下:
public class Hunger {
    // 1、创建类中私有构造
    private Hunger() {

    }

    // 2、创建该类的私有静态实例
    private static Hunger instance = new Hunger();

    // 3、创建公有静态方法返回静态实例对象
    public static Hunger getInstance() {
        return instance;
    }
}
  • 2.在Test类当中编写测试代码,验证实例出来的两个对象的引用是否相同。
public class Test {
    public static void main(String[] args) {
        Hunger one = Hunger.getInstance();
        Hunger two = Hunger.getInstance();

        System.out.println(one);
        System.out.println(two);
    }
}
  • 3.运行代码,结果是两个实例化对象的引用指向了相同的位置。
    这里写图片描述

3.2、懒汉式的代码实现

  • 1.在singleton包下新建一个名为Laziness的类,代码如下所示。
public class Laziness {
    // 1、创建类中私有构造
    private Laziness() {
    }

    // 2、创建该类的私有静态实例
    private static Laziness instance = null;

    // 3、创建公有静态方法返回静态实例对象(创建时并不初始化,知道第一次调用时才进行初始化)
    public static Laziness getInstance() {
        if (instance == null)
            instance = new Laziness();
        return instance;
    }
}
  • 2.修改Test测试代码。
public class Test {
    public static void main(String[] args) {
        Hunger one = Hunger.getInstance();
        Hunger two = Hunger.getInstance();

        System.out.println(one);
        System.out.println(two);

        System.out.println("==============");

        Laziness Three = Laziness.getInstance();
        Laziness four = Laziness.getInstance();

        System.out.println(Three);
        System.out.println(four);
    }
}
  • 3.运行代码结果如下所示,完成预期。
    这里写图片描述

4、饿汉式VS懒汉式

  • 饿汉式模式是一种典型的空间换时间的编码方式,由于在类加载时就创建实例,则该类的实例在第一次加载的时候速度非常快,但是在初始化的时候就得为实例对象开辟存储空间,并且存在的周期变长,会造成内存空间的浪费。
  • 懒汉式模式是一种典型的时间换空间的编码方式,由于在类加载时并不直接实例化,而在第一次使用时再去实例化,因此该类在第一次使用时加速度变慢。,同样地,在该类在创建之后,若从未使用其对象实例,也不会造成内存空间的浪费。
  • 在项目的实际开发中,还存在一种多线程的场景,即需要在某一时刻执行多项任务,饿汉式在类加载时就完成了对象的实例化创建,即便多个线程并发操作,它访问的实例对象也是唯一的,所以说饿汉式线程是安全的;而懒汉式则是在第一次使用时才会去进行实例化的创建,当多个线程并发操作时,由于线程的切换则可能导致一定的线程风险。当然针对懒汉式存在的线程风险,我们也是有很多方法可以去解决的,以便保证操作时的线程唯一。譬如:
    1. 同步锁
    2. 双重校验锁
    3. 静态内部类
    4. 枚举

5、总结

  • 单例模式的优点
    1. 在内存中只有一个对象,节省内存空间;
    2. 避免频繁的创建销毁对象,提高性能;
    3. 避免对共享资源的多重占用问题;
  • 单例模式的缺点
    1. 扩展比较困难;
    2. 如果实例化后的对象长期不利用,系统将默认为垃圾进行回收,造成对象状态的丢失;
  • 单例模式的使用场景
    1. 创建对象时占用资源过多,但同时又需要用到该类对象;
    2. 对系统内资源要求统一读写,如读写配置信息等;
    3. 当多个实例存在可能引发程序逻辑错误,如号码生成器等。

猜你喜欢

转载自blog.csdn.net/chaixingsi/article/details/82055121