首页 > 其他分享 >设计模式—创建型模式之单例模式

设计模式—创建型模式之单例模式

时间:2023-10-26 21:01:29浏览次数:29  
标签:obj 模式 线程 SingletonObject 单例 static 设计模式 懒汉

设计模式—创建型模式之单例模式

介绍

单例模式说明:一个单一的类,负责创建自己的对象,同时确保系统中只有单个对象被创建。

单例模式特点:

  1. 某个类只能有一个实例;(构造器私有)
  2. 它必须自行创建这个实例;(自己编写实例化逻辑)
  3. 它必须自行向整个系统提供这个实例;(对外提供实例化方法)

单例模式图示如下:

单例模式图

饿汉式

饿汉式,比较简单,代码如下:

public class SingletonObject {
    private final static SingletonObject obj = new SingletonObject();
    private SingletonObject() {
        System.out.println("创建了单例对象");
    }
    public static SingletonObject getInstance() {
        return obj;
    }
}

懒汉式—效率低下实现方式1(线程安全)

获取实例的方法是static的,我们可以给整个方法加一个锁,这样锁的对象是整个类,可以保证线程安全:

代码实现如下:

public class SingletonObject {
	//懒汉式
	private static SingletonObject obj;
	//保证构造器私有,外部不能实例化
	private SingletonObject() {
		System.out.println("创建了单例对象");
	}
	//这种锁粒度太大,导致效率低
	public static synchronized SingletonObject getInstance() {
		//懒汉式,如果没有再去创建
		if(obj == null) {
			obj = new SingletonObject();
		}
		return obj;
	}
}

懒汉式—效率低下实现方式2(线程安全)

我们可以不给整个方法加锁,可以给如下代码块加锁,但是这样的方式效率还是低;

public class SingletonObject {
	//懒汉式
	private static SingletonObject obj;
	//保证构造器私有,外部不能实例化
	private SingletonObject() {
		System.out.println("创建了单例对象");
	}
	//但是这样锁粒度还是太大,进入到方法里边再加锁,这样效率还低
	public static SingletonObject getInstance() {
		synchronized(SingletonObject.class) {
			//懒汉式,如果没有再去创建
			if(obj == null) {
				obj = new SingletonObject();
			}
		}
		return obj;
	}
}

懒汉式—线程不安全

我们能否在创建时再加锁呢,于是有了如下的代码:

public class SingletonObject {
	//懒汉式
	private static SingletonObject obj;
	//保证构造器私有,外部不能实例化
	private SingletonObject() {
		System.out.println("创建了单例对象");
	}
	//线程不安全
	public static SingletonObject getInstance() {
		//懒汉式,如果没有再去创建
		if(obj == null) {
			synchronized(SingletonObject.class) {
				obj = new SingletonObject();
			}
		}
		return obj;
	}
}

这样的方式是线程不安全的,比如:

  1. 有两个线程,线程1和线程2都进入到方法中,判断到obj为null;
  2. 假如线程1先获取到锁,为obj赋值完成,然后方法运行结束,返回obj;
  3. 然后线程2获取到锁,又把obj赋值一次;此时两次返回的就不是同一个对象了。

懒汉式—双重检查锁

下面的懒汉式设计模式,用了双重检查锁;

public class SingletonObject {
    //懒汉式,线程可见性
    private volatile static SingletonObject obj;
    //首先保证构造器私有,外部不能实例化

    private SingletonObject() {
        System.out.println("创建了单例对象");
    }
    /**
     * 双重检查锁 + 内存可见性volatile
     */
    public static SingletonObject getInstance() {
        //懒汉式,如果没有再去创建
        if (obj == null) {
            synchronized (SingletonObject.class) {
                if(obj == null){
                    obj = new SingletonObject();
                }
            }
        }
        return obj;
    }
}

方法getInstance()中,如果单例对象为空,才会把方法块加锁,获取到锁的线程创建对象完成并赋值成功,且obj保证了线程可见性,其他线程便可以感知到obj不为null,就不会再创建赋值了。

标签:obj,模式,线程,SingletonObject,单例,static,设计模式,懒汉
From: https://www.cnblogs.com/nicaicai/p/17790371.html

相关文章

  • pageofficeV6强制留痕模式编辑
    转载:强制留痕模式编辑强制留痕模式编辑注意本文中展示的代码均为关键代码,复制粘贴到您的项目中,按照实际的情况,例如文档路径,用户名等做适当修改即可使用。Word中的“痕迹”功能可以跟踪文档中所做的更改。痕迹可以包括添加、删除、移动和格式更改等。Word提供了“痕迹保留”功......
  • Nacos单机模式配置远程数据源、配置身份认证
    1.nacos介绍官网链接:https://nacos.io/zh-cn/docs/what-is-nacos.htmlGithub:https://github.com/alibaba/nacos/Nacos/nɑ:kəʊs/是DynamicNamingandConfigurationService的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos致力于......
  • 结构型模式(三) 外观模式
    外观模式:是为了给子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得子系统更加容易使用。减少系统之间的耦合性,提高了灵活性和安全性角色:外观类、子系统类classCpu:defstart(self):print('cpustart')defstop(self):......
  • 视频主动上报模式
    视频主动上报模式是一种监控系统中的重要技术,它主要涉及摄像机的数据传输和上报。这种模式通常包括以下步骤:摄像机安装与连接:首先,需要将摄像机安装在需要监控的位置,并确保摄像机能够正常工作。同时,需要将摄像机通过网线或无线网络连接到网络中,以便能够将拍摄到的视频数据传输到......
  • python读取和写入txt等文件,文件打开模式,文件对象常用函数
     ......
  • 手摸手Redis7配置哨兵模式(一主二从三哨兵)
    安装redis#安装gccyum-yinstallgccgcc-c++#安装net-toolsyum-yinstallnet-tools#官网https://redis.io/cd/opt/wgethttp://download.redis.io/releases/redis-7.0.4.tar.gz解压至/opt/目录下tar-zxvfredis-7.0.4.tar.gz-C/opt/#编译安装makemakeinstallINS......
  • RocketMQ的3种消息发送模式是什么?如何确保消息不丢失?
    RocketMQ发送消息的三种模式分别是:同步发送、异步发送和单向发送。1、同步发送模式(Sync)发送方发送消息后会等待消息被成功发送到消息队列服务器并收到确认消息后才返回发送结果给调用方。这种模式下,发送方会阻塞等待Broker返回发送结果,直到收到确认消息或者超时。应用场景:对消息的......
  • nRF52840 SYSTEM OFF模式下唤醒的唤醒方式
    参考spec上的说明,唤醒源有5个。分别是:1.GPIO外设发出的DETECT信号2.LPCOMP模块发出的ANADETECT信号3.NFC模块发出的SENSE信号4.USB模块VBUSpin出现有效电压时5.给复位管脚一个信号供参考示例在如下工程中,NCS示例有待再发现\nRF5_SDK_17.1.0\examples\peripheral......
  • 关于32位MCU GPIO八种工作模式配置
    参考链接:https://mp.weixin.qq.com/s/vgYzCcxmsfn7BGWERHfITQ通常,32位MCU的GPIO有多种配置方式,如STM32、CH32MCU的GPIO引脚都有八种配置方式,总体可分为两类:输入和输出。其中:输入可分为:浮空输入上拉输入下拉输入模拟输入输出可分为开漏输出推挽输出复用开漏输出复用......
  • Ftp主被动模式
    ftp[-pinegvd][host]pftp[-inegvd][host]用户通过ftp这个程序来使用Internet上的标准文件传输协议(FTP)。本程序允许用户向远端网站发送文件,或从远端网站接收文件。注意:CentOS7中需要自己安装此程序。(1).参数选项参数选项可以在命令行启动ftp时指定,也可以在ftp命令解释模......