编程(40)----------单例模式
在简单总结单例模式之前, 需要了解一下背景知识-----为何会有单例模式?
想象一个这样的场景, 打游戏的时候, 尝试很多次, 都未通关. 这种情况下是否会考虑查一下攻略? 一个好的攻略甚至可能连每一关的每一个场景由多少只怪物都说的清清楚楚. 再比如, 在以前上学的时候, 为了方便理解和使用一些解题技巧, 是不是会有一些口诀? 例如, 奇变偶不变, 符号看象限. 亦或者,为了能够下棋下的更好, 可能会尝试去看看棋谱. 棋谱里会把常见的开局解法给一一列举出来.
单例模式也是一个道理. 就跟上述的一样, 是为了方便代码的规范所做出的一些明确的规定,或者说代码的写法. 以此提高写代码的效率. 这些模式种类很多, 单例模式只是其中的一个. 顾名思义,单例模式就是只允许创建一个实例的模式.
代码写法有两种: 饿汉模式和懒汉模式
//饿汉模式
class Singleton{//先将实例创建出来private static Singleton instance = new Singleton();//若要使用唯一实例, 通过统一的方法public static Singleton getInstance(){return instance;}//将构造方法设为私有, 则无法在该类外使用该构造方法private Singleton(){}
}public class demo3 {public static void main(String[] args) {}
}
//懒汉模式
class Singleton{//先将实例创建出来private static Singleton instance = null;//若要使用唯一实例, 通过统一的方法public static Singleton getInstance(){if (instance == null){instance = new Singleton();}return instance;}//将构造方法设为私有, 则无法在该类外使用该构造方法private Singleton(){}
}public class demo3 {public static void main(String[] args) {}
}
代码本身并不复杂, 涉及到的也是一些简单的Java语法. 但是, 存在一个问题: 这两种模式是否线程安全?
在此之前, 得清楚衡量线程是否安全, 其中一个重要的指标就是, 是否该代码或者说线程只进行了读操作. 若既有读操作又有其他操作, 如写改操作. 那这个线程多半是不安全的.
再回到这俩个模式的代码中. 不难看出懒汉模式存在一个if语句的判定, 这其实就是读操作. 要先读入才能进行判定改写, 因此懒汉模式线程不安全. 反之, 饿汉模式只有读操作, 是安全的.
基于以上的结论, 假设要在多线程中使用懒汉模式. 就必须将其进行优化.
首先就从判定改写入手. 在多线程中, 由于读入, 判定, 改写的操作不具有原子性, 是分开的操作. 很有可能一个线程刚判定完, 为null, 另一个线程也开始判定, 结果也为null. 在这种情况下二者都会依照代码在此基础上new一个对象. 但是这实际上是违背了单例模式的规则. 因此要对整个过程进行加锁操作.
synchronized (SingletonLazy.class) {if (instance == null) {instance = new SingletonLazy();}}
其次, 在线程很多的情况下, 需要每次都进行if判定是否为空吗? 很明显不需要, 单例模式只存在一个实例. 也就是说无需每次都加锁进行if判定, 效率过低. 当已经有某个线程new了一个对象以后,直接返回对象即可, 因此可以将代码进行再次优化:
public static SingletonLazy getSingletonLazy(){if (instance == null) {synchronized (SingletonLazy.class) {if (instance == null) {instance = new SingletonLazy();}}}return instance;}
除此以外, 当线程非常多且代码没有什么变化的时候, 系统自身会优化, 即发生内存可见性问题. 还有可能发生代码执行顺序调换的问题. 为解决以上问题, 使用volatile关键字一次性解决. 因此综合以上优化, 懒汉模式的多线程代码就差不多可以写出来了:
//懒汉模式
class SingletonLazy{private volatile static SingletonLazy instance = null;public static SingletonLazy getSingletonLazy(){if (instance == null) {synchronized (SingletonLazy.class) {if (instance == null) {instance = new SingletonLazy();}}}return instance;}private SingletonLazy(){}
}public class demo4 {public static void main(String[] args) {}
}
------------------------------最后编辑于2023.6.1晚上八点左右
相关文章:

编程(40)----------单例模式
在简单总结单例模式之前, 需要了解一下背景知识-----为何会有单例模式? 想象一个这样的场景, 打游戏的时候, 尝试很多次, 都未通关. 这种情况下是否会考虑查一下攻略? 一个好的攻略甚至可能连每一关的每一个场景由多少只怪物都说的清清楚楚. 再比如, 在以前上学的时候, 为了…...

Java开发 - 让你少走弯路的Redis主从实现单节点哨兵模式
前言 前一篇中,我们讲解了Redis主从的搭建方式,其实很简单呐有木有,都是配置,连句代码都没有,是不是感觉高估了Redis主从的搭建方式?哈哈,没关系,跟着博主,包你全会。今…...

Java的Atomic原子类
Java SDK 并发包里提供了丰富的原子类,我们可以将其分为五个类别,这五个类别提供的方法基本上是相似的,并且每个类别都有若干原子类。 对基本数据类型的变量值进行原子更新;对对象变量的指向进行原子更新;对数组里面的…...

离线语音控制新方案,NRK3303语音识别芯片在智能风扇的应用
随着科技的不断发展,智能家居已经成为人们日常生活中不可或缺的一部分,涌现出越来越多的智能设备,如智能门锁、智能灯泡、智能冰箱等,这些设备为人们的生活带来了更多的便利和创新。其中作为常见的风扇通过添加智能语音控制功能&a…...
在树莓派3B+上安装Pytorch1.7
在树莓派3B上安装Pytorch1.7(应该是最简单的方法了)_package libopenblas-dev has no installation cand_Chauncey_Wang的博客-CSDN博客由于项目要求,我需要在树莓派上安装pytorch这就有几个问题,首先吧,咱们和外面之间有一道长城,…...

Java性能权威指南-总结4
Java性能权威指南-总结4 Java性能调优工具箱操作系统的工具和分析CPU运行队列磁盘使用率网络使用率 Java监控工具基本的VM信息 Java性能调优工具箱 操作系统的工具和分析 CPU运行队列 快速小结 检查应用性能时,首先应该审查CPU时间。优化代码的目的是提升而不是…...

c语言全局变量和局部变量问题汇总
✅作者简介:嵌入式领域优质创作者,博客专家 ✨个人主页:咸鱼弟 🔥系列专栏:单片机设计专栏 📃推荐一款求职面试、刷题神器👉注册免费刷题 1、关键字static的作用是什么? 定义静态变…...

14.3:给定一个由字符串组成的数组strs,必须把所有的字符串拼接起来,返回所有可能的拼接结果中字典序最小的结果
给定一个由字符串组成的数组strs,必须把所有的字符串拼接起来,返回所有可能的拼接结果中字典序最小的结果 贪心写法 首先注意的一点是:如果两个字符串的长度相同,“abc”,“abd”,肯定是“abc”的字典序最…...

C++ 项目实战:跨平台的文件与视频压缩解压工具的设计与实现
C实战:跨平台文件与视频压缩解压工具的设计与实现 一、引言(Introduction)1.1 项目背景与目标1.2 技术选型:C、FFmpeg、libarchive、libzip、QtCFFmpeglibarchivelibzipQt 二、设计思路与框架(Design Philosophy and F…...

C和指针(二)数据
数据类型 1,C语言中仅有四种基本数据类型——整型、浮点型、指针、聚合类型(数组、结构等)。 2,整型包括字符、短整型、整型、长整型,且可以分为有符号和无符号两种版本。 1)长整型至少和整型一样长&#…...

PyTorch基础学习(一)
一.简介 PyTorch是一个基于Python的开源机器学习框架,它提供了丰富的工具和接口,用于构建和训练深度学习模型。PyTorch的主要特点包括: 动态计算图: PyTorch使用动态计算图,这意味着在模型构建过程中可以实时地进行计…...

chatgpt赋能python:Python代做:让您的网站更友好的SEO利器
Python代做:让您的网站更友好的SEO利器 如果您是一位网站管理员或者SEO工程师,您一定知道SEO对于网站的重要性。那么在SEO中,Python代做可以为您提供什么?在本文中,我们将通过介绍Python代做的技术和方法,…...

2022年都快结束了,还有人不会安卓录屏?在安卓上录制屏幕的的实现方式
前言 在我之前的文章 《以不同的形式在安卓中创建GIF动图》 中,我挖了一个坑,可以通过录制屏幕后转为 GIF 的方式来创建 GIF。只是当时我只是提了这么一个思路,并没有给出录屏的方式,所以本文的内容就是教大家如何通过调用系统 A…...

px rem em rpx 区别 用法
任意浏览器的默认字体高都是16px。所有未经调整的浏览器都符合: 1em16px。那么12px0.75em,10px0.625em。为了简化font-size的换算,需要在css中的body选择器中声明Font-size62.5%,这就使em值变为 16px*62.5%10px, 这样12px1.2em, 10px1em, 也就是说只需要…...

忆享聚焦|ChatGPT、AI、网络数字、游戏……近期热点资讯一览
“忆享聚焦”栏目第十四期来啦!本栏目汇集近期互联网最新资讯,聚焦前沿科技,关注行业发展动态,筛选高质量讯息,拓宽用户视野,让您以最低的时间成本获取最有价值的行业资讯。 目录 行业资讯 1.科技部部长王志…...

[Daimayuan] 树(C++,动态规划,01背包方案数)
有一棵 n n n 个节点的以 1 1 1 号点为根的有根树。现在可以对这棵树进行若干次操作,每一次操作可以选择树上的一个点然后删掉连接这个点和它的儿子的所有边。 现在我们想知道对于每一个 k k k ( 1 ≤ k ≤ n 1≤k≤n 1≤k≤n),最少需要多少次操作能…...

如何选择源代码加密软件
(SDC沙盒)和DLP、文档加密、云桌面等,其优缺点做客观比较如下: 比较内容安全容器(SDC沙盒)DLP文档加密云桌面代表厂家*信达卖咖啡、赛门贴科亿*通、IP噶德、*盾、*途四杰、深*服设计理念以隔离容器加准入技术为基础,构…...

TO-B类软件产品差异化
产品差异化,是在市场众多同质化产品中,突出自身产品亮点的重要方式。对于客户来讲其选择是多种多样的,与其花费大量的时间研究每一家产品的特点,还不如直接选择品牌更大、价格更低的产品来的直接,因此显而易见的突出产…...

设计模式之美-实战一(上):业务开发常用的基于贫血模型的MVC架构违背OOP吗?
领域驱动设计(Domain Driven Design,简称DDD)盛行之后,这种基于贫血模型的传统的开发模式就更加被人诟病。而基于充血模型的DDD开发模式越来越被人提倡。所以,我打算用两节课的时间,结合一个虚拟钱包系统的…...

ChatGPT如何训练自己的模型
ChatGPT是一种自然语言处理模型,它的任务是生成自然流畅的对话。如果想要训练自己的ChatGPT模型,需要进行大量的数据收集、预处理、配置训练环境、模型训练、模型评估等过程。本文将详细介绍这些过程,帮助读者了解如何训练一个高品质的ChatGP…...

springboot使用线程池的实际应用(一)
在实际Spring Boot项目中,我们可以使用Java的原生多线程或者使用Spring自带的线程池进行多线程编程。多线程的好处在于能够提高应用程序的运行效率,特别是在某些计算密集型场景下。以下是一些使用多线程的典型场景: 并发处理请求:…...

ESP-8266学习笔记
1、学习地址 【XMF09F系列资源】基于MicroPython的ESP8266物联网应用开发-赛教资源目录汇总-小蜜蜂笔记 Quick reference for the ESP8266 — MicroPython latest documentation 2、MicroPython及相关开发资源 3、固件烧录与uPyLoader的使用 烧录教程参考: https://www.…...

Java泛型简单的使用
前言 Java里面的泛型在实际开发中运用的很多,学过C的同学一定知道C的模板,而Java中的泛型,一定程度上和它还是挺像的。 相信写Java的人,大都有用过List的实现类ArrayList。在Java没有泛型之前,它的内部是一个Object的…...

深度探索:Qt CMake工程编译后的自动打包策略
深度探索:Qt CMake工程编译后的自动打包策略 1. 引言(Introduction)1.1 Qt和CMake的基本概念(Basic Concepts of Qt and CMake)1.2 自动打包的重要性(Importance of Automatic Packaging) 2. Qt…...

2.7 编译型和解释型
2.7 编译型和解释型 前面我们使用java和javac命令把Hello,World!在控制台输出。那为什么输出,这里我们需要掌握两个知识点。编译型语言和解释型语言。在计算机的高级编程语言就分为编译型语言和解释型语言。而我们的Java既有编译型的特点也有…...

校园网自动登陆(河南科技学院)
1. 介绍 河南科技学院校园网自动登陆(新乡的很多系统相似,可能也可以用?),java版。可以实现电脑,路由器,软路由的自动认证wifi,后续会上传docker版本的。 源码地址 github:https://…...

C++11 override和final关键字
C11中的override和final关键字是为了增强代码的编译时类型检查和面向对象设计中的继承机制。 override关键字用于显示地表明派生类中的成员函数覆盖了基类中的虚函数。当派生类中的函数与基类中的虚函数签名不同或者没有使用override关键字时,编译器会给出警告或错…...

kafka的log存储解析
kafka的log存储解析——topic的分区partition分段segment以及索引等 引言Kafka中的Message是以topic为基本单位组织的,不同的topic之间是相互独立的。每个topic又可以分成几个不同的partition(每个topic有几个partition是在创建topic时指定 的),每个…...

4.文件系统
组成 Linux:一切皆文件 索引节点(I-node) I-node(Index Node):文件系统的内部数据结构,用于管理文件的元数据和数据块。 文件的元数据:包括文件的权限、拥有者、大小、时间戳、索引…...

Shell脚本case in esac分支语句应用
记录:434 场景:Shell脚本case in esac分支语句应用。 版本:CentOS Linux release 7.9.2009。 1.case in esac格式 格式: case 值 in 模式1)expression;; 模式2)expression;; 模式n)expression;; esac 解析:case…...