JavaEE之线程(7)_单例模式(设计模式概念、单例模式优点、懒汉、饿汉模式)

一、什么是设计模式?

单例模式是设计模式中较为常见的一种。那么,什么是单例模式?

  1. 设计模式(Design Pattern)都是一些相对优秀的解决方案,很多问题都是典型的、有代表性的问题,学习设计模式,我们就不用自己从头来解决这些问题,相当于在巨人的肩膀上,复用这些方案即可。
  2. 设计模式已经成为专业人士的常用词汇,不懂不利于交流。
  3. 能让你设计的系统更加专业,让系统有更好的架构。

目的:使用设计模式是为了可重用性代码,让代码更容易被他人理解,保证代码可靠性。


二、单例模式

基本概念:
 单例模式是一种设计模式,它的目的是保证一个类只有一个实例,并提供一个全局的访问点。使用单例模式可以避免多次创建对象,节省内存空间,同时也可以保证数据的一致性。

约定某个类,只能有唯一个对象。通过编码技巧,让编译器进行强制检査,(在类里面提前把对象创建好,并且把构造方法设为 private)

2.1 单例模式的好处

  • [ 节省系统资源] :在系统中,如果有多个实例会造成资源浪费,而使用单例模式可以减少这种浪费。
  • [简化了对象访问] :单例模式提供了一个全局的访问点,因此可以简化访问过程。

2.2 懒汉模式

懒汉式单例模式:

在第一次使用时才创建单例对象。缺点是需要考虑线程安全问题。
单线程版代码实例:

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

 上述代码懒汉模式的实现是线程不安全的

  1. 线程安全问题发生在首次创建实例时。如果在多个线程中同时调用 getInstance 方法,就可能导致创建出多个实例;
  2. 一旦实例已经创建好了, 后面再多线程环境调用 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;}
}

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

代码在加锁的基础上, 做出了进一步改动:

  1. 使用双重 if 判定, 降低锁竞争的频率.。
  2. 给 instance 加上了 volatile。
package single;/*** @author Zhang* @date 2024/5/717:12* @Description:*/class  SingletonLazy{private  static volatile  SingletonLazy instance = null;    //懒汉模式public  static SingletonLazy getInstance(){if(instance == null){//如果对象已经有了,线程就安全了,此时就可以不加锁了//如果对象还没有,存在在线程不安全的风险,就需要加锁synchronized (SingletonLazy.class){  //一旦加锁,就可能产生阻塞if (instance == null){   //判定是否要new一个对象instance = new SingletonLazy();}}}return instance;}private  SingletonLazy(){ }}public class Test2 {public static void main(String[] args) {}
}

注意理解上述代码双重 if 判定 / volatile:

  1. 理解双重 if 判定 / volatile:加锁 / 解锁是一件开销比较高的事情。 而懒汉模式的线程不安全只是发生在首次创建实例的时候,因此后续使用的时候, 不必再进行加锁了。
  2. 外层的 if 就是判定下看当前是否已经把 instance 实例创建出来了。同时为了避免 “内存可见性” 导致读取的 instance 出现偏差, 于是补充上 volatile。

2.3 饿汉模式

饿汉式单例模式:在类加载时创建单例对象。缺点是不支持延迟加载。

  1. 优点:单例只有在使用时才被实例化,一定程度上节约了资源 ;
  2. 缺点:加入synchronized关键字,造成不必要的同步开销。不建议使用。
package single;/*** @author Zhang* @date 2024/5/716:58* @Description:*/class  Singleton{/*** 1. 在类的内部,提供一个现成的实例* 2. 把构造方法设置为private,避免其他代码能够创建出实例* 通过上述方式,就强制了其他程序员在使用这个类的时候,就不会创建出多个对象了*/private static  Singleton instance  = new Singleton();    //这里的创建时机,是在类加载的时候(比较早的时机)--饿汉模式//通过这个方法来获取刚刚的实例//后续如果想使用这个类的实例,都通过getInstance() 方法来获取public static Singleton getInstance(){return instance;}//把构造方法设置为私有,此时类外面的代码,就无法new相互这个类的对象了private Singleton(){ }}public class Test1 {public static void main(String[] args) {Singleton s1 = Singleton.getInstance();Singleton s2 = Singleton.getInstance();System.out.println(s1 == s2); //true}
}

2.4 单例模式的总结

 我们只介绍单例实现方式的饿汉模式、懒汉模式两种方式,其他单例模式的内容可以通过网络资源进行查阅。接下来让我们总结一下不同单例模式的区别:
在这里插入图片描述

总结

 以上就是今天要讲的内容,本文仅仅简单介绍了设计模式的概念,什么是单例模式?包括懒汉模式和饿汉模式,并写出了相应的参考代码。最后,对不同实现方式的单例模式进行了总结。

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

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

相关文章

为什么本科毕业后我坚定地选择了就业而不是考研?

大家好,我是小布丁。今天来聊聊我为什么本科毕业后选择了就业而不是考研。 在整个大学期间,我被亲戚拷问最多的问题就是:准备考研吗?相信很多大学生都遇到过这种情况吧。 如果你说准备还好,亲戚大概率就不会问下去&a…

元组推导式

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 使用元组推导式可以快速生成一个元组,它的表现形式和列表推导式类似,只是将列表推导式中的“[]”修改为“()”。例如&#xf…

python深入解析字符串操作的八大神技

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、字符串的长度与切片 示例代码 二、去除多余的空格 示例代码 三、字符串的开头与包含…

元组的创建和删除

目录 使用赋值运算符直接创建元组 创建空元组 创建数值元组 删除元组 自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 元组(tuple)是Python中另一个重要的序列结构&#…

关于堆排序

今天我们不刷力扣了,我们来复习(手撕)一下数据结构中的八大排序算法之一,堆排序 基本概念: 堆是一种特殊的树形数据结构,即完全二叉树。 堆分为大顶堆和小顶堆: 大顶堆:每个节点的值…

OrangePi KunPengPro | 开发板开箱测评之学习与使用

OrangePi KunPengPro | 开发板开箱测评之学习与使用 时间:2024年5月23日20:51:12 文章目录 OrangePi KunPengPro | 开发板开箱测评之学习与使用概述1.参考2.资料、工具3.使用3-1.通过串口登录系统3-2.通过SSH登录系统3-3.安装交叉编译工具链3-4.复制文件到设备3-5.第…

【组合数学】常考试题答案

一、单项选择题(每小题3分,共15分) 1. 用3个“1”和4个“0”能组成( )个不同的二进制数字。 A. 35 B. 36, C. 37, D. 38 2. 整除300的正整数的个数为(  )。 A. 14…

Anaconda+CUDA+CUDNN+Pycharm+Pytorch安装教程(第一节 Anconda安装)

1.选择和对应的anconda版本 官网地址:Index of / (anaconda.com) 下载地址:Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 2.安装流程 (1)下载安装包 (2)点击next (3)点击I agree &a…

解决Flutter位于悬浮窗口时,应用Logo不更新问题

问题描述 我已经更换了应用Logo,但是发现应用处于悬浮窗口时,logo还是更改之前的?下面的图片只是示意。 解决方案 终端命令 rm -rf ~/Library/Developer/Xcode/DerivedData2.xcode视图内解决 先在顶部找到 Xcode --> Setting --> Lo…

操作系统入门系列-MIT6.828(操作系统工程)学习笔记(二)----课程实验环境搭建(wsl2+ubuntu+quem+xv6)

MIT6.S081(操作系统)学习笔记 操作系统入门系列-MIT6.828(操作系统)学习笔记(一)---- 操作系统介绍与接口示例 操作系统入门系列-MIT6.828(操作系统工程)学习笔记(二&am…

福昕PDF编辑器自定义快捷方式

你是否为用不惯福昕PDF编辑器自带的快捷键而发愁?今天,我和大家分享一下如何设置自己想要的快捷键方式,希望能对大家有帮助。 步骤一:打开福昕PDF编辑,并找到更多命令 步骤二:切换到键盘一栏,并…

分布式专题

一:分布式事务 1、理论基础 分布式事务主要区分本地事务 什么是本地事务(Local Transaction)?本地事务也称为数据库事务或传统事务(相对于分布式事务而言)。尤其对于数据库而言,为了数据安全…

Docker快速搭建Oracle服务

服务器:CentOS7.9 1.安装docker yum install -y docker 2. 设置镜像加速 修改 /etc/docker/daemon.json 文件并添加上 registry-mirrors 键值 阿里云的docker镜像需要自己注册账号,也可以不注册账号,直接使用下面的连接。 也可以写入多…

【C++ 】学习问题及补充

一.自定义类型不初始化直接就赋值&#xff0c;比如string类会怎么样 vectr<string>里已经给每个string对象已经分配好空间&#xff0c;为什么不初始化再赋值会报错 在C中&#xff0c;std::string类是一个动态字符串类&#xff0c;它内部管理着一个字符数组&#xff0c;用…

【蓝桥杯】国赛普及-

题目列表 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) P9420 [蓝桥杯 2023 国 B] 子 2023 / 双子数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<bits/stdc.h> using llunsigned long long; #define int ll const int N2e510; int k0; std::string s; int…

【传知代码】无监督动画中关节动画的运动表示-论文复现

文章目录 概述动画技术的演进原理介绍核心逻辑环境配置/部署方式小结 本文涉及的源码可从无监督动画中关节动画的运动表示该文章下方附件获取 概述 该文探讨了动画在教育和娱乐中的作用&#xff0c;以及通过数据驱动方法简化动画制作的尝试。近期研究通过无监督运动转移减少对…

Java进阶学习笔记30——BigDecimal

BigDecimal&#xff1a; 用于解决浮点型运算的&#xff0c;出现结果失真的问题。 运行结果&#xff1a; package cn.ensource.d4_bigdecimal;import java.math.BigDecimal;public class Test {public static void main(String[] args) {// 目标&#xff1a;了解BigDecimal类do…

8、Qt—Log4Qt使用小记2(每日产生文件)

前言&#xff1a; 开发平台&#xff1a;Win10 64位 开发环境&#xff1a;Qt Creator 13.0.0 构建环境&#xff1a;Qt 5.15.2 MSVC2019 64位 例如&#xff1a;上一篇文章中笔者记录了Log4qt的编译及配置使用&#xff0c;这篇文章重点写下每天产生文件到指定文件夹中&#xff0c;…

5.1 Go 函数的定义与调用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

Spring Boot集成testcontainers快速入门Demo

1.什么是testcontainers&#xff1f; Testcontainers 是一个用于创建临时 Docker 容器进行单元测试的 Java 库。当我们想要避免使用实际服务器进行测试时&#xff0c;它非常有用。&#xff0c;官网介绍称支持50多种组件。​ 应用场景 数据访问层集成测试&#xff1a; 使用My…