单例模式---饿汉式、懒汉式

news2024/10/6 10:31:33

一、什么是单例模式

单例模式,指的是一个类中的对象只能有一个,它在内存中只会创建一次对象的设计模式

二、饿汉式

public class SingleTon {
    // 私有的构造方法
    private SingleTon() {

    };

    // 1. 饿汉式
    private static SingleTon instance = new SingleTon(); // 一开始就初始化好

    // 线程是安全的,
    // 因为这个实例是一开始就创建好的,无论几个线程来调,他只是读这个instance变量,不存在写
    public static SingleTon getInstance() {  // 对外提供获取这个实例的方法
        return instance;
    }
}

饿汉式的问题是: 一开始就实例化对象,如果实例化过程非常耗时,并且最后这个对象若没有被使用,白白造成资源浪费 

 

三、懒汉式

public class SingleTonL {
    private SingleTonL() {

    };
    private static SingleTonL instance1 = null;
    // 2.懒汉式  线程是不安全的
    public static SingleTonL getInstance() {
        if  (instance1 == null) {
            instance1 = new SingleTonL();  // 这里面是一个写入的动作
        }
        return instance1;
    }
}

对于懒汉式这一设计模式,线程是不安全的,针对这个问题,给出了解决方案

方案:使用  synchronized  关键字

  假如有多个线程中都调用了getInstance方法,那么都走到 if (instance== null) 判断时,可能同时成立,因为instance初始化时默认值是null。这样会导致多个线程中同时创建instance对象,即instance对象被创建了多次,违背了只创建一个instance对象的初衷

// 解决上述线程不安全的问题
public class SingleTonL1 {
    private SingleTonL1() {

    };

   
    private static SingleTonL1 instance1 = null;
    // 2.懒汉式  线程是不安全的

    public static  SingleTonL1 getInstance() {
        synchronized (SingleTonL1.class) {
                if  (instance1 == null) {
                    instance1 = new SingleTonL1();  // 这里面是一个写入的动作
                }
        }
       
        return instance1;
    }
}

还有一个问题就是如果instance != null , 按照上述代码,这个线程也会进入锁,,,影响执行的效率。需要在前面在进行是否为空判断

// 解决上述线程不安全的问题
class SingleTonL1 {
    private SingleTonL1() {

    };

    private static SingleTonL1 instance1 = null;
    // 2.懒汉式  线程是不安全的

    public static  SingleTonL1 getInstance() {
        if (instance1 == null) {  // 先判断,如果不为null, 则不用加锁,直接返回
            synchronized (SingleTonL1.class) {
                if  (instance1 == null) {
                    instance1 = new SingleTonL1();  // 这里面是一个写入的动作
                }
            }
        }
        return instance1;
    }
}

 

多线程下的内存可见性

 当A线程更改了变量instance后,线程B又访问,此时需要让线程B访问到的是变量instance的被更改后的值。(也就是说线程B去取这个变量的时候必须从主存取,不能从缓存取。)

解决方案: volatile

 

 

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

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

相关文章

【Java 基础】26 枚举

文章目录 1. 什么是枚举2. 定义3. 使用1)常量2)遍历3)switch 4. 属性和方法1)属性2)方法 5. 实现原理6. 使用场景总结 1. 什么是枚举 枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计…

第17章:随堂复习与企业真题(反射机制)

第17章:随堂复习与企业真题(反射机制) 一、随堂复习 1. 反射的概述(熟悉) Java给我们提供了一套API,使用这套API我们可以在运行时动态的获取指定对象所属的类,创建运行时类的对象,…

12.08

1.头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QDebug>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);~Widget(); signals:v…

One-to-Few Label Assignment for End-to-End Dense Detection阅读笔记

One-to-Few Label Assignment for End-to-End Dense Detection阅读笔记 Abstract 一对一&#xff08;o2o&#xff09;标签分配对基于变换器的端到端检测起着关键作用&#xff0c;最近已经被引入到全卷积检测器中&#xff0c;用于端到端密集检测。然而&#xff0c;o2o可能因为…

Aligning Large Multi-Modal Model with Robust Instruction Tuning

Abstract 尽管多模态任务取得了有希望的进展&#xff0c;但当前的大型多模态模型&#xff08;LMM&#xff09;很容易产生与相关图像和人类指令 不一致的描述的幻觉。 LRV-指令。我们通过引入第一个大型且多样化的视觉指令调整数据集来解决这个问题&#xff0c;该数据集名为大…

DOS 批处理 (一)

DOS 批处理 1. 批处理是什么&#xff1f;2. DOS和MS-DOS3. 各种操作系统shell的区别Shell 介绍图形用户界面&#xff08;GUI&#xff09;shell命令行界面&#xff08;CLI&#xff09;的 shell命令区别 1. 批处理是什么&#xff1f; 批处理(Batch)&#xff0c;也称为批处理脚本…

el-tree数据量过大,造成浏览器卡死、崩溃

el-tree数据量过大&#xff0c;造成浏览器卡死、崩溃 场景&#xff1a;树形结构展示&#xff0c;数据超级多&#xff0c;超过万条&#xff0c;每次打开都会崩溃 我这里采用的是引入新的插件虚拟树&#xff0c;它是参照element-plus 中TreeV2改造vue2.x版本虚拟化树形控件&…

基于微服务架构的外卖系统源码开发

在当前互联网时代&#xff0c;外卖行业蓬勃发展&#xff0c;用户对于高效、智能的外卖服务需求不断增加。为了满足这一需求&#xff0c;采用微服务架构的外卖系统成为了开发的主流方向。本文将探讨基于微服务的外卖系统源码开发&#xff0c;涉及到关键技术和示例代码。 1. 微…

远程控制如何赋能智能制造?贝锐向日葵制造业场景案例解析

随着数字化转型在制造业的不断深入&#xff0c;企业在产线端也逐渐投入更多智能化设备&#xff0c;数字化、智能化设备其中一个比较显著的优势就是可以依托互联网实现远程运维和调试&#xff0c;大大提升产线设备的稳定性和工作效率&#xff1b;而远程调试运维一个重要的实现方…

ALTERNET STUDIO 9.1 Crack

ALTERNET STUDIO 9.1 发布 宣布 AlterNET Studio 9.1 版本今天上线。AlterNET Studio 9.0 是一个中期更新&#xff0c;重点是改进我们所有的组件库。 以下是 AlterNET Studio 9.1 的发布亮点&#xff1a; Roslyn C# 和 Visual Basic 解析器现在支持代码修复/代码重构。 代码修复…

el-date-picker时间控制范围为过去时间不可选

<el-date-picker :picker-options"startPickerOptions()" value-format"yyyy-MM-dd HH:mm:ss" v-model"form.applyFixPlan" type"datetime" placeholder"选择日期时间"> </el-date-picker> 在method中定义star…

【ESP32 IDF】ESP32移植u8g2库,实现oled界面显示

ESP32移植u8g2库&#xff0c;实现oled界面显示 1. 简单描述2. 环境准备1. 硬件准备2. 软件准备 3. IIC屏幕 【基于 ssd1362 256*64 】4. SPI屏幕 【基于 ssd1306 128*32】 1. 简单描述 开发方式为 IDF5.0参考连接为 iic基于esp-idf移植使用u8g2 spi基于esp-idf移植使用u8g2 …

插入排序——直接插入排序和希尔排序(C语言实现)

文章目录 前言直接插入排序基本思想特性总结代码实现 希尔排序算法思想特性总结代码实现 前言 本博客插入排序动图和希尔排序视频参考大佬java技术爱好者&#xff0c;如有侵权&#xff0c;请联系删除。 直接插入排序 基本思想 直接插入排序是一种简单的插入排序法&#xff…

广播和组播

1. 广播 1.1 知识点 INADDR_ANY代表本机所有地址 常用方法当你将套接字绑定到INADDR_ANY&#xff0c;它会监听所有可用的网络接口&#xff0c;这意味着它将接受来自所有本地IP地址的传入连接或数据包 1.1.1 广播的流程 广播发送端&#xff1a; ----> 添加广播属性 1、建立套…

JAVA后端自学技能实操合集

JAVA后端自学技能实操 内容将会持续更新中,有需要添加什么内容可以再评论区留言,大家一起学习FastDFS使用docker安装FastDFS(linux)集成到springboot项目中 内容将会持续更新中,有需要添加什么内容可以再评论区留言,大家一起学习 FastDFS 组名&#xff1a;文件上传后所在的 st…

MySQL中是如何insert数据的

正常insert数据&#xff0c;MySQL并不会显式加锁&#xff0c;而是通过聚簇索引的trx_id索引作为隐式锁来保护记录的。比如两个事务对一个非唯一的索引情况添加&#xff0c;会造成幻读 但在某些特殊情况下&#xff0c;隐式锁会转变为显式锁&#xff1a; 记录之间有间隙锁inser…

Qt使用Cryptopp生成HMAC-MD5

近期项目中HTTPS通讯中&#xff0c;token需要使用HMAC-MD5算法生成&#xff0c;往上找了一些资料后&#xff0c;仍不能满足自身需求&#xff0c;故次一记。 前期准备&#xff1a; ①下载Cryptopp库&#xff08;我下载的是8.8.0 Release版本&#xff09;&#xff1a;Crypto Li…

基础课19——知识图谱问答引擎

1.概念 知识图谱是一种结构化的知识表示方式&#xff0c;将实体、属性和关系以图形的形式进行表达和组织。它通过对知识进行结构化建模&#xff0c;将不同实体之间的关系进行编码&#xff0c;形成一个图结构的知识网络。知识图谱的目标是将人类的知识整合到一个统一的框架中&a…

Segment Anything--SAM框架(二)

文章目录 prologuepaper && codeImage encoderPrompt encoderLightweight mask decoderMaking the model ambiguity-aware prologue 没什么事&#xff0c;写一写SAM的paper中关于模型框架的部分和实际代码部分。 paper && code SAM有三个组件&#xff0c;如图…

图数据库知识点9 | 大数据框架与图数据架构异同

开门见山&#xff0c;直奔主题&#xff0c;接续前面的知识点&#xff1a; 【图数据库知识点1|图数据库与关系型数据库的区别&#xff1f;】 【图数据库知识点2 | 图思维方式】 【图数据库知识点3 | 图数据库解决了什么问题&#xff1f;】 【图数据库知识点4 | 图计算与图数…