【多线程】单例模式

news2024/12/24 8:22:14

目录

饿汉模式

懒汉模式-单线程版

懒汉模式-多线程版

懒汉模式-多线程版(改进)


单例是一种设计模式。

啥是设计模式 ?
设计模式好比象棋中的 " 棋谱 ". 红方当头炮 , 黑方马来跳 . 针对红方的一些走法 , 黑方应招的时候有一些固定的套路. 按照套路来走局势就不会吃亏 .
软件开发中也有很多常见的 " 问题场景 ". 针对这些问题场景 , 大佬们总结出了一些固定的套路 . 按照这个套路来实现代码, 也不会吃亏 .

单例模式能保证某个类在程序中只存在唯一一份实例, 而不会创建出多个实例.

这一点在很多场景上都需要 . 比如 JDBC 中的 DataSource 实例就只需要一个 .
单例模式具体的实现方式 , 分成 " 饿汉 " " 懒汉 " 两种 .
首先要分析清楚,在JAVA中哪些对象是全局唯一的:
.class对象   比如String.class;
用static修饰的变量。

饿汉模式

类加载的同时 , 创建实例 .
class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() {
        return instance;
   }
}

    既然是单例,那么通过new方式去获取对象是有歧义的,所以要将构造方法私有化,不能让外部去new这个对象。

饿汉模式书写简单,不容易出错。

懒汉模式-单线程版

类加载的时候不创建实例 . 第一次使用的时候才创建实例。
class Singleton {
    private static Singleton instance = null;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
       }
        return instance;
   }
}

但是放在多线程中,就会创建多个对象,出现线程不安全现象。

懒汉模式-多线程版

上面的懒汉模式的实现是线程不安全的。
线程安全问题发生在首次创建实例时 . 如果在多个线程中同时调用 getInstance 方法 , 就可能导致创建出多个实例.
一旦实例已经创建好了 , 后面再多线程环境调用 getInstance 就不再有线程安全问题了 ( 不再修改instance 了 )
加上 synchronized 可以改善这里的线程安全问题 .
class Singleton {
    private static Singleton instance = null;
    private Singleton() {}
    public synchronized static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
       }
        return instance;
   }
}

懒汉模式-多线程版(改进)

以下代码在加锁的基础上 , 做出了进一步改动:
  • 使用双重 if 判定, 降低锁竞争的频率.
  • instance 加上了 volatile.
class Singleton {
    private static volatile Singleton instance = null;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
           if (instance == null) {
               instance = new Singleton();
               }
           }
       }
        return instance;
   }
}
理解双重 if 判定 / volatile:
加锁 / 解锁是一件开销比较高的事情 . 而懒汉模式的线程不安全只是发生在首次创建实例的时候 .因此后续使用的时候, 不必再进行加锁了 .
外层的 if 就是判定下看当前是否已经把 instance 实例创建出来了 .
同时为了避免 " 内存可见性 " 导致读取的 instance 出现偏差 , 于是补充上 volatile .
当多线程首次调用 getInstance, 大家可能都发现 instance null, 于是又继续往下执行来竞争锁 ,其中竞争成功的线程, 再完成创建实例的操作 .
当这个实例创建完了之后 , 其他竞争到锁的线程就被里层 if 挡住了 . 也就不会继续创建其他实例 .

常见面试题:

描述一下单例模式:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/514847.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5.11 C高级作业

编写一个名为myfirstshell.sh的脚本,它包括以下内容。 1、包含一段注释,列出您的姓名、脚本的名称和编写这个脚本的目的 2、和当前用户说“hello 用户名” 3、显示您的机器名 hostname 4、显示上一级目录中的所有文件的列表 5、显示变量PATH和HOME的…

高性能网络 SIG 月度动态:长期投入得到业界认可,新增一位 virtio reviewer

高性能网络 SIG(Special Interest Group) :在云计算时代,软硬件高速发展,云原生、微服务等新的应用形态兴起,让更多的数据在进程之间流动,而网络则成为了这些数据流的载体,在整个云时…

Hive概述和安装

hive简介 Hive:由Facebook开源用于解决海量结构化日志的数据统计工具。 Hive是基于Hadoop的一个数据仓库工具,将结构化的数据文件映射为一张表,并提供类SQL(HQL)查询功能。 Hive本质:将HQL转化成MapReduce程序 (1&am…

无锁队列实现及使用场景

写在前面 在看无锁队列之前,我们先来看看看队列的操作。队列是一种非常重要的数据结构,其特性是先进先出(FIFO),符合流水线业务流程。在进程间通信、网络通信间经常采用队列做缓存,缓解数据处理压力。根据…

device_node转换成platform_device

device_node转换成platform_device 文章目录 device_node转换成platform_device转换规则主要核心函数of_default_bus_match_tablearmarm64of_platform_register_reconfig_notifier Linux内核是如何将device_node转换成platform_deviceof_platform_populate函数处理根节点下的子…

在ubuntu连接Xlight FTP Server

一 在windows上搭建服务器 http://www.xlightftpd.com/download.htm 使用英文版,使防止在ubuntu中登录中文版时,显示乱码 新建用户和用户对应的服务器目录 如下所示,默认只有读权限 全都勾选 勾选完毕后的效果 在目录中放一个文件&#…

10款常用的原型设计工具,包含一键生成原型工具

原型图是产品设计师日常工作的“常客”,原型图软件也扮演着产品设计师的“武器”角色。 许多新产品设计师不知道如何选择原型图软件。本文盘点了10个优秀的原型图软件,让我们来看看。 1.即时设计 即时设计是一款免费的在线 UI 设计工具,无…

【Java数据结构】排序

排序 插入排序希尔排序选择排序堆排序冒泡排序快速排序序列的分割Hoare法挖坑法快慢指针法 优化1 - 三数取中优化2- 数据规模小时的插入 归并排序 插入排序 直接插入排序是一种简单的插入排序法,其基本思想是: 把待排序的记录按其关键码值的大小逐个插…

Jetson Orin环境安装Opencv+Cuda以及vscode环境配置

文章目录 一:Opencv Cuda源码的下载、编译1.卸载jetson上自带的无cuda加速Opencv2.安装Opencv依赖库3.下载 OpenCV 和 opencv_contrib 源码4.编译安装 OpenCV、opencv_contrib 二:Opencv 的环境配置三:Vscode 中的Opencv环境配置四&#xff…

系统分析师---系统建模相关高频考试知识点

系统规划---成本效益分析 评价信息系统经济效益常用的方法主要有成本效益分析法,投入产出分析法和价值工程方法。盈亏平衡法常用于销售定价; 可行性分析 系统规划是信息系统生命周期的第一个阶段,其任务是对企业的环境、目标以及现有系统的状况进行初步调查,根据企业目标…

张正友相机标定原理

相机标定 记录1.1 张正友相机标定相关 参考 记录 最小二乘法:A^T A x 0 奇异值分解的办法求解最小二乘法 因为可以假设标定板平面在世界坐标系Z0的平面上, 1.1 张正友相机标定相关 单目相机标定实现–张正友标定法(包含具体的实现以及C代码&#xff0…

《花雕学AI》ChatGPT Shortcut Chrome 扩展:让生产力和创造力加倍的 ChatGPT 快捷指令库

你是否想要与一个智能的对话伙伴聊天,或者让它帮你完成各种任务,如写作、编程、摘要、翻译等?如果是的话,你可能会对 ChatGPT 感兴趣。ChatGPT 是一个基于 GPT-3.5 的对话式人工智能,可以与用户进行自然、流畅、有趣的…

文件看不见了,内存还占着容量的找回教程

U盘文件突然不见了但还占用内存空间的解决方法 如果文件看不见了但内存占用仍然存在,可能是因为以下原因: 文件被隐藏。某些操作系统允许隐藏文件,这些文件只能在文件浏览器中被找到。 文件被损坏。如果文件损坏,它可能不会显示在…

Python图形化编程开源项目拼码狮PinMaShi

开源仓库 #项目地址 https://github.com/supercoderlee/pinmashi https://gitee.com/supercoderlee/pinmashiPinMaShi采用electron开发,图形化拖拽式编程有效降低编程难度,对Python编程的初学者非常友好;积木式编程加快Python程序的开发&…

黑马Redis笔记-高级篇

黑马Redis笔记-高级篇 1、Redis持久化(解决数据丢失)1.1 RDB持久化1.1.1 定义1.1.2 异步持久化bgsave原理 1.2 AOF持久化1.3 RDB和AOF比较 2、Redis主从(解决并发问题)2.1 搭建主从架构2.2 主从数据同步原理2.2.1 全量同步2.2.2 增…

基于哈里斯鹰算法优化的核极限学习机(KELM)分类算法 -附代码

基于哈里斯鹰算法优化的核极限学习机(KELM)分类算法 文章目录 基于哈里斯鹰算法优化的核极限学习机(KELM)分类算法1.KELM理论基础2.分类问题3.基于哈里斯鹰算法优化的KELM4.测试结果5.Matlab代码 摘要:本文利用哈里斯鹰算法对核极限学习机(KELM)进行优化&#xff0c…

【小梦C嘎嘎——启航篇】基本语法格式:namespace ?

基本语法格式:namespace ?😎 前言🙌namespace 是什么?namespace 的意义何在? 总结撒花💞 😎博客昵称:博客小梦 😊最喜欢的座右铭:全神贯注的上吧&…

springboot + vue 部署 阿里云云服务器 ECS

安装所需文件 安装mysql5.7 下载MySQL的yum源配置 wget http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm安装MySQL的yum源 yum -y install mysql57-community-release-el7-11.noarch.rpm使用yum方式安装MySQL5.7(下载需要点时间&#xf…

【 断电延时继电器 电源监视 导轨安装 JOSEF约瑟 HJZS-E202 AC220V】

品牌:JOSEF约瑟型号:HJZS-E202名称:断电延时继电器额定电压:110、220VDC/AC;100VAC触点容量:250V/5A功率消耗:≤4.2W返回系数:10%额定电压 系列型号: HJZS-E202断电延时…

4.4 栈实现及其应用

目录 栈 顺序栈 创建栈: 清空栈: 判断栈是否空 : 进栈 : 出栈 : 取栈顶元素: 栈 栈是限制在一端进行插入操作和删除操作的线性表(俗称堆栈) 允许进行操作的一端称为“栈顶” 另一固定端称为“栈底” 当栈中没有元素时称为“空栈”…