系列一、 单例设计模式

一、单例设计模式

1.1、概述

单例模式(Singleton Pattern)是Java中最简单的设计模式之一。这种类型的设计模式属于创建者模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

1.2、应用场景

只需要一个实例,例如:各种Manager、各种Factory

二、单例模式的结构

2.1、单例模式主要有以下角色

  • 单例类:只能创建一个实例的类
  • 访问类:使用单例类

2.2、单例模式的实现

  • 饿汉式:类加载就会导致该单例对象被创建
  • 懒汉式:类加载不会导致该单例对象被创建,当首次使用该对象时才会创建

2.3、单例模式-饿汉式

2.3.1、静态成员变量

java 复制代码
public class SingletonDemo1 {

    // 1、私有构造方法
    private SingletonDemo1() {
    }

    // 2、在当前类中创建本类对象
    private static SingletonDemo1 instance = new SingletonDemo1();

    // 3、对外提供获取本类实例对象的公共访问方式
    public static SingletonDemo1 getInstance() {
        return instance;
    }
}

2.3.2、静态代码块

java 复制代码
public class SingletonDemo2 {

    // 1、私有构造方法
    private SingletonDemo2() {

    }

    // 2、在当前类中声明当前类的类型变量
    private static SingletonDemo2 instance;

    // 3、在静态代码块中进行赋值
    static {
        instance = new SingletonDemo2();
    }

    // 4、对外提供获取该类对象的方法
    public static SingletonDemo2 getInstance() {
        return instance;
    }

}

2.3.3、存在的问题

由于对象的创建是随着类的加载而创建,所以存在内存浪费的问题。

2.4、单例模式-懒汉式

2.4.1、线程不安全

java 复制代码
/**
 * 
 * @Description 懒汉式:线程不安全
 * 存在的问题:多线程情况下,会创建多个实例
 */
public class SingletonDemo3 {

    // 1、私有构造方法
    private SingletonDemo3() {

    }

    // 2、在当前类中声明当前类的类型变量
    private static SingletonDemo3 instance; // 这是声明了一个该类型的变量,并没有进行赋值

    // 3、对外提供获取该类对象的方法
    public static SingletonDemo3 getInstance() {
        if (instance == null) {
            instance = new SingletonDemo3();
        }
        return instance;
    }
}

2.4.2、线程安全

java 复制代码
/**
 * @Description 懒汉式:线程安全
 * 存在的问题:
 *      对于getInstance()方法来说,绝大部分的操作都是读操作,读操作是线程安全的,所以我们没必要让每个线程必须持有锁才能调用该方法,
 *   而且加锁在多线程场景下,会严重影响性能。
 */
public class SingletonDemo4 {

    // 1、私有构造方法
    private SingletonDemo4() {

    }

    // 2、在当前类中声明当前类的类型变量
    private static SingletonDemo4 instance; // 这是声明了一个该类型的变量,并没有进行赋值

    // 3、对外提供获取该类对象的方法
    public static synchronized SingletonDemo4 getInstance() {
        if (instance == null) {
            instance = new SingletonDemo4();
        }
        return instance;
    }

}

2.4.3、双重锁检查机制【推荐】

java 复制代码
/**
 * @Description 懒汉模式:双重锁检查机制
 */
public class SingletonDemo5 {
    // 1、私有构造方法
    private SingletonDemo5() {

    }

    /**
     * 2、在当前类中声明当前类的类型变量
     * 说明:添加volatile关键字之后的双重检查锁模式是一种比较好的单例实现模式,能够保证在多线程的情况下线程安全,
     * 并且不会影响性能。
     */
    private static volatile SingletonDemo5 instance; // 这是声明了一个该类型的变量,并没有进行赋值

    // 3、对外提供获取该类对象的方法
    public static SingletonDemo5 getInstance() {
        // 3.1、第一次判断,如果instance不为null,不需要抢占资源,直接返回
        if (instance == null) {
            synchronized (SingletonDemo5.class) {
                // 3.2、第二次判断
                if (instance == null) {
                    instance = new SingletonDemo5();
                }
            }
        }
        return instance;
    }
}
相关推荐
杨充1 天前
10.可测试性实战设计
设计模式·开源·代码规范
杨充1 天前
9.重构十二式的实战
设计模式·开源·代码规范
杨充1 天前
6.设计原则的全景图
设计模式·开源·全栈
杨充1 天前
2.面向对象的特性
设计模式
杨充1 天前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充1 天前
8.反模式与坏味道
设计模式·开源·代码规范
杨充1 天前
3.接口vs抽象类比较
设计模式
咖啡八杯1 天前
文法、BNF与AST
java·设计模式·解释器模式·ast·文法
咖啡八杯1 天前
GoF设计模式——解释器模式
java·后端·spring·设计模式