javaEE-多线程案例-单例模式

news2025/1/1 10:47:09

目录

啥是设计模式?

一.饿汉式

实现步骤:

二.懒汉式

实现步骤:

三、懒汉式优化1

四.懒汉式优化2

五.懒汉式优化3

总代码:


单例模式是一种设计模式。

啥是设计模式?

设计模式好⽐象棋中的"棋谱".红⽅当头炮,⿊⽅⻢来跳.针对红⽅的⼀些⾛法,⿊⽅应招的时候有⼀ 些固定的套路.按照套路来⾛局势就不会吃亏。软件开发中也有很多常⻅的"问题场景".针对这些问题场景,⼤佬们总结出了⼀些固定的套路.按照这个套路来实现代码,也不会吃亏。

单例模式能够保证在线程中只创建唯一一份实例,不会创建出多份实例。

一.饿汉式

类加载的同时,创建实例。

实现步骤:

1.在类内实例化一个 私有,静态 的该类实例。

2.将构造器私有化。

3.提供一个公共的方法,返回该类的实例化对象。

代码展示:


/**
 *  //单例模式
 *    饿汉式
 */
class Instance{
    //1.实例化Instance线程,将其设为私有,静态
    private static Instance single=new Instance();
    //2.私有化构造器
    private Instance(){
    }
    //3.提供公共方法,返回类内创建的实例对象
    public static Instance getInstance(){
        return single;
    }
}

二.懒汉式

类加载的时候不会创建实例,第一次使用的时候才创建实例.

实现步骤:

1.创建私有,静态该类对象single,并设为null.

2.将构造器私有化。

3.提供公共方法,判断该类是否已经被创建,若single=null,则实例化对象,否则,直接返回single实例。

代码展示:

class InstanceLazy1{
    // 1.创建该类对象,设为私有,静态
    // 先不实例化 将其设为null
    private static InstanceLazy1 single=null;
    //2.将构造器私有化
    private InstanceLazy1(){}
    //3.提供公共的方法,判断该类是否被实例化过
    //若未被实例化,则实例化对象,
    //否则直接返回single
    public static InstanceLazy1 getInstance(){
        if(single==null){
            single=new InstanceLazy1();
        }
        return single;
    }
}

三、懒汉式优化1

在单线程下,懒汉式是线程安全的,但是若是在多线程下,懒汉模式就可能出现线程安全问题。

在两个线程t1,t2下:

为防止在多线程下,创建出多个对象,要使用synchronized锁,将if和new打包成一个原子的,在判断之前,先上锁,这样就能避免在第一次创建对象的时候,引发线程安全问题。

(这里创建多个对象虽然不会出现异常,无实质性错误,但是若创建的对象占用的内存空间是巨大的,此时若创建多个,就会带来非常大的代价,甚至有可能使内存满,)

(return new InstanceLazy1(),这里写错了

但是,加锁之后,每次判断该类是否已被创建,都要先上锁,这势必会降低代码的运行效率,且可能出现 线程安全 只可能发生在第一次要创建对象的时候。

四.懒汉式优化2

为提高效率,在上锁之前,先判断是否是否创建过对象。若未创建,再上锁,再次判断是否实例化了对象。注意两次判断的作用是不同的。

第一次判断是为了提高代码执行效率,第二次是判断是否已创建对象。

五.懒汉式优化3

指令重排序问题也有可能引发线程安全问题.

指令重排序:代码优化的一种方式,调整代码的执行顺序,在原来逻辑不变的前提下,提高代码的执行效率。

可以使用volatile关键字来避免底层自动进行指令重排序.

懒汉式可能发生指令重排序问题是在创建对象的时候:

创建对象,分为三步:

1.申请一段内存空间

2.在这个内存上调用构造方法,创建出这个实例

3.将这个内存地址赋给single引用变量.

正常情况下,是按照1 2 3 来执行的,但有时会按照1 3 2来执行,也能创建出实例对象,这就是指令从排序.

但是在多线程下,若按照1 3 2来执行 就会引发线程安全问题.

这里,在代码重排序后创建出来的single对象,属于未初始化的全“0”值,若该对象中有属性或方法,一旦在后面的代码使用该对象,就可能会报错!!!

在single对象处加上volatile关键字修饰,就能禁止代码重排序,防止这样的对象被创建,解决线程安全问题。

总代码:

/**
    单例模式
    懒汉式
/
class Instance{
    //1.实例化Instance线程,将其设为私有,静态
    private static Instance single=new Instance();
    //2.私有化构造器
    private Instance(){
    }
    //3.提供公共方法,返回类内创建的实例对象
    public static Instance getInstance(){
        return single;
    }
}

/**
 * 单例模式
 * 饿汉式 优化版
 */
class InstanceLazy{
    // 定义该类对象,设为私有,静态
    // 先不实例化对象 将其设为null

    //优化3:为防止出现 指令重排序问题, 防止出现线程安全问题
    // 给single对象 加volatile关键字,底层不再进行指令重排序
    private static volatile InstanceLazy single=null;
    //将构造器私有化
    private InstanceLazy(){}
    //提供获取对象的公共方法,在方法内创建对象
    public static InstanceLazy getInstance(){
        Object locker=new Object();
        //判断
        // 若还未实例化对象,就实例化对象,
        if(single==null){//优化2:当第一次创建后,之后就不用再判断了,也就不用再加锁了,
                        //为了提高代码的效率,先判断一下,若不为空,则不再加锁,直接返回对象
            synchronized(locker){//懒汉式 优化1 :为防止出现线程安全问题
                                //将判断为空和创建新线程,设置为一个 原子的
                if(single==null){
                    single=new InstanceLazy();
                }
            }
        }
        //若已创建过对象,就直接返回创建过的对象
        return single;
    }
}
/**
    测试用例
/
public class Thread{
    public static void main(String[] args) {

        Instance instance1=Instance.getInstance();
        Instance instance2=Instance.getInstance();
        System.out.println(instance1==instance2);//true 这两个对象是同一个对象实例

        InstanceLazy single3=InstanceLazy.getInstance();
        InstanceLazy single4=InstanceLazy.getInstance();
        System.out.println(single3==single4);//true single1和single2是同一个对象
    }
}

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

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

相关文章

TCP Analysis Flags 之 TCP Out-Of-Order

前言 默认情况下,Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态,并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时,会对每个 TCP 数据包进行一次分析,数据包按照它们在数据包列表中出现的顺序进行处理。可…

鸿蒙开发实战之“使用HiLog和HiSysEvent进行日志与系统事件管理”

HiLog和HiSysEvent作为鸿蒙(HarmonyOS)系统中进行日志记录和系统事件管理的关键组件,为开发者提供了强大的工具来追踪系统行为、调试应用以及监控设备状态。它们不仅简化了日志管理和事件追踪的流程,还提高了开发效率和系统可维护…

机器学习之PCA降维

主成分分析(PCA,Principal Component Analysis) 主成分分析(PCA)是一种常见的无监督学习技术,广泛应用于数据降维、数据可视化以及特征提取等任务。PCA的目标是通过线性变换将数据从高维空间映射到低维空间…

【CSS in Depth 2 精译_098】17.3:CSS 动画延迟技术与填充模式设置 + 17.4:通过 CSS 动画传递意图的秘诀

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第五部分 添加动效 ✔️【第 17 章 动画】 ✔️ 17.1 关键帧17.2 3D 变换下的动画设置 17.2.1 添加动画前页面布局的构建17.2.2 为布局添加动画 17.3 动画延迟与填充模式 ✔️17.4 通过动画传递意图…

python+PyMuPDF库:(一)创建pdf文件及内容读取和写入

目录 文档操作 打开文档 获取文档信息 删除页 复制页 移动页 选择重构合并 保存关闭 页对象操作 内容读取 获取页对象的字体样式 插入文本标签 插入文本内容 字体设置 insert_text添加文本 insert_textbox添加文本 插入图片 获取页面注释、链接、表单字段 …

Datawhale AI冬令营 动手学AI Agent

背景——什么是Agent 在人工智能领域,agent可以指一个能够感知环境并作出决策以实现特定目标的系统。比如,一个聊天机器人(chatbot)就是一个agent,它能够理解用户的输入并给出相应的回复。 学习目标 学会使用百宝箱…

高精度保形滤波器Savitzky-Golay的数学原理、Python实现与工程应用

面向信号处理的特征保持平滑技术 在数据分析领域,信号处理中的噪声问题始终是一个重要议题。无论是实验数据、金融时间序列还是其他形式的信号处理,噪声都会干扰目标模式和趋势的识别。尽管存在多种降噪方法,但在处理短时信号时,…

九点标定+旋转标定

眼在手外方式 1.夹取make点位置要求 机械手夹具夹持一个款标定板或者物料露出make点让视觉定位抓取 高度:与产品识别高度一致 左右位置:在相机视野内可以拍到make点 2.机械手走9个点移动位置要求(九点标定) 保证make在视野内…

RealityCapture导入视频序列失败

问题原因:如果导入的视频文件存在多余的元数据,那么在这里会发生导入失败。 以本人华为手机拍摄的一段.mp4视频为例: 利用ffmpeg在窗口命令行中检查你的视频—— ffmpeg -i your_video_name.mp4your_video_name是你的视频文件名 如下图所示&…

计算机网络|数据流向剖析与分层模型详解

文章目录 一、网络中的数据流向二、计算机网络通信模型1.OSI 模型2.TCP/IP 模型3.TCP/IP五层模型3.1 分层架构描述3.2各层地址结构3.3UDP数据包报头结构 三、总结 一、网络中的数据流向 在计算机网络中,数据的流向是指数据从发送端到接收端的传输路径。数据流向涉及…

正则表达式(三剑客之awk)

1.awk工具的使用 1.1 截取文档中的某个段 1)打印以 : 为分隔的第一个字段 [rootlocalhost ~]# head -n3 /etc/passwd | awk -F : {print $1} 2)注意事项 -F:作用是指定分隔符。如果不加分隔符,则以空格或者tab为分隔符 print&…

【基于rust-wasm的前端页面转pdf组件和示例】

基于rust-wasm前端页面转pdf组件和示例 朔源多余的废话花哨的吹牛那点东西要不要拿来试试事到如今 做个美梦 我觉得本文的意义在于,wasm扩展了浏览器的边界,但是又担心如同java的web applet水土不服. 如同我至今看不出塞班和iOS的不同下载地址:在github的备份 朔源…

图扑可视化赋能挖掘机高效操控

数字孪生挖掘机通过图扑可视化实时数据呈现和精准环境模拟,提升操作精度与施工效率,助力施工项目可视化管理,优化资源配置,为工程机械行业带来了新的智能化革新。

【多维DP】力扣3366. 最小数组和

给你一个整数数组 nums 和三个整数 k、op1 和 op2。 你可以对 nums 执行以下操作: 操作 1:选择一个下标 i,将 nums[i] 除以 2,并 向上取整 到最接近的整数。你最多可以执行此操作 op1 次,并且每个下标最多只能执行一…

支付域——“奖、惩、贴“特殊清算

摘要 在现代的服务平台经济中,比如网约车、外卖服务等,奖惩机制是用来管理服务提供者行为和确保服务品质的一种重要工具。所谓的“奖惩贴”就是这种机制中的一种具体形式,它包括了给予服务提供者的奖金、罚款和补贴。这些措施能够激励平台商…

网易企业邮箱登陆:保障数据安全

网易企业邮箱是一款为企业提供安全可靠的电子邮件服务的工具。通过网易企业邮箱,企业可以实现员工之间的高效沟通和信息共享,同时保障数据的安全性。 企业邮箱的安全性是企业信息保护的重要组成部分。网易企业邮箱采用了多层加密技术,确保邮件…

java常用类(下)

笔上得来终觉浅,绝知此事要躬行 🔥 个人主页:星云爱编程 🔥 所属专栏:javase 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 一、Math 类 1.1基本介…

计算机的错误计算(一百九十四)

摘要 用两个大模型计算 其中,一个大模型通过化简,得出正确结果 0;而另外一个在化简过程中出现错误,得出了错误结果。 例1. 计算 下面是一个大模型的推导化简过程。 以上为一个大模型的回答。 下面是另外一个大模型的回复。 点评…

电脑缺失sxs.dll文件要怎么解决?

一、文件丢失问题:以sxs.dll文件缺失为例 当你在运行某个程序时,如果系统提示“找不到sxs.dll文件”,这意味着你的系统中缺少了一个名为sxs.dll的动态链接库文件。sxs.dll文件通常与Microsoft的.NET Framework相关,是许多应用程序…

初始c语言第一个c语言项目

第一个c语言项目 //c语言中一定要有main函数 //主函数//printf是一个库函数 //专门用来打印数据//std 标准 //i-input //o-output // #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h>//c语言规定main函数是程序的入口 //标准的主函数的写法 int main() {printf(&qu…