系列一、 单例设计模式

一、单例设计模式

1.1、概述

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

1.2、应用场景

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

二、单例模式的结构

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

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

2.2、单例模式的实现

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

2.3、单例模式-饿汉式

2.3.1、静态成员变量

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2024/2/25 22:51
 * @Model Description:
 * @Description: 单例模式饿汉式:静态成员变量
 * @特点:类加载就会导致该单例对象被创建
 * 存在的问题:由于对象的创建是随着类的加载而创建,所以存在内存浪费的问题。
 */
public class HungryManDemo1 {

    /**
     * 1、私有构造方法
     */
    private HungryManDemo1() {
        System.out.println(Thread.currentThread().getName() + "\t 构造方法SingletonDemo1被调用了");
    }

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

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

2.3.2、静态代码块

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2024/2/25 22:51
 * @Model Description:
 * @Description: 单例模式饿汉式:静态代码块
 * @特点:类加载就会导致该单例对象被创建
 * 存在的问题:由于对象的创建是随着类的加载而创建,所以存在内存浪费的问题。
 */
public class HungryManDemo2 {

    /**
     * 1、私有构造方法
     */
    private HungryManDemo2() {
        System.out.println(Thread.currentThread().getName() + "\t 无参构造方法SingletonDemo2()被调用了");
    }

    /**
     * 2、在当前类中创建本类对象
     */
    private static HungryManDemo2 instance;

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

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

2.3.3、存在的问题

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

2.4、单例模式-懒汉式

2.4.1、线程不安全

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2024/2/25 23:27
 * @Model Description:
 * @Description: 单例模式懒汉式:静态成员变量
 * 存在的问题:多线程情况下,会创建多个实例
 */
public class LazyManDemo1 {

    /**
     * 1、私有构造方法
     */
    private LazyManDemo1() {
        System.out.println(Thread.currentThread().getName() + "\t 我是构造方法LazyManDemo1()");
    }

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

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

}

2.4.2、线程安全

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2024/2/25 23:27
 * @Model Description:
 * @Description: 单例模式懒汉式:静态成员变量
 */
public class LazyManDemo2 {

    /**
     * 1、私有构造方法
     */
    private LazyManDemo2() {
        System.out.println(Thread.currentThread().getName() + "\t 我是构造方法LazyManDemo2()");
    }

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

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

}

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

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2024/2/25 23:27
 * @Model Description:
 * @Description: 单例模式懒汉式:静态成员变量
 * 双重检查锁模式,保证线程安全
 */
public class LazyManDemo3 {

    /**
     * 1、私有构造方法
     */
    private LazyManDemo3() {
        System.out.println(Thread.currentThread().getName() + "\t 我是构造方法LazyManDemo3()");
    }

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

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

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值