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

news2024/11/15 14:08:15

一、什么是设计模式?

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

  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.coloradmin.cn/o/1698460.html

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

相关文章

外企也半夜发布上线吗?

0 别把问题想得太复杂 如果有灰度发布的能力,最好白天发布;如果没有灰度发布,只能在半夜发布。 即使有灰度发布能力,也不要沾沾自喜,好好反思一下你们的灰度发布是否真的经得起考验,还是仅仅是装装样子。…

Python语言绘制好看的小提琴图、箱形图、散点图、山脊图和柱状图等等

废话不多说,今天给大家分享一个,使用python绘制小提琴图、箱形图、散点图、山脊图和柱状图等等 图中的数据是随机生成的,图例,图注以及坐标题目各种信息,具体内容大家可以自己修改~ 效果图如下所示 👇&a…

web如何做接口层面自动化测试?

接口层面约等于集成化测试,且需要启动web容器 一般web项目的,代码都是按照分层开发的,业务主要是集中在service和dao层,而我们如果仅仅是利用之前的单元测试,然后把依赖的代码直接mock掉,仅仅测试controller这一块是没…

数据结构(四)

数据结构(四) 算法算法的特征算法和程序的区别怎么样评判一个算法的好坏 常见的查找算法线性树状哈希查找构建哈希函数的方法质数求余法解决冲突 算法 一堆指令的有序集合 算法的特征 唯一性:每一句话只有一种解释 有穷性:算法能…

第十课,while循环

一,认识循环是什么 循环普遍存在于日常生活中,同样,在程序中,循环功能也是至关重要的基础功能。 当程序需要重复执行某一段代码,利用循环可以轻松完成工作 例如我要你打印100次上课,直接写100次print&…

SpringBoo+vue3整合讯飞星火3.5通过webscoket实现聊天功能(全网首发)附带展示效果

API版本:Spring Boot 整合讯飞星火3.5通过接口Api接口实现聊天功能(首发)复制粘贴即可使用,后续更新WebSocket实现聊天功能_讯飞星火web聊天-CSDN博客https://blog.csdn.net/qq_53722480/article/details/138865508?csdn_share_t…

基于xilinx FPGA的 FFT IP使用例程说明文档(可动态配置FFT点数,可计算信号频率与幅度)

目录 1 概述2 IP examples功能3 IP 使用例程3.1 IP设置3.2 fft_demo端口3.3 例程框图3.4 仿真结果3.5 仿真验证得出的结论4 注意事项5例程位置 1 概述 本文用于讲解xilinx IP 的FFT ip examples的功能说明,方便使用者快速上手。 参考文档:《PG109》 2 …

推荐13款常用的Vscode插件,提高前端日常开发效率

1. Live Server Live Server 插件是一个用于前端开发的扩展,它的主要作用是提供一个本地开发服务器,以便实时预览和调试网页应用程序。其最大特点在于热重载,即开发者可实时预览代码效果。 因为Live Server 允许开发者在浏览器中实时预览您正…

Android Webview加载pdf文件无法缩放问题

WebView设置开启页面缩放: settings webView.getSettings(); settings.setSupportZoom(true); settings.setJavaScriptEnabled(true); settings.setUseWideViewPort(true); settings.setLoadWithOverviewMode(true); settings.setBuiltInZoomControls(true); sett…

集成开发环境GoLand安装配置结合内网穿透实现ssh远程访问服务器

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

MOS选型及其参数解析

背景: 整理现有常用元器件选型,日后使用时针对性观看,生成列表链接如下: https://blog.csdn.net/caozhaokun/article/details/126069701 作者:Cayden 时间:2024/05/26 一、MOS选用现状 MOS是电路设计…

【Text2SQL】Spider 数据集

论文:Spider: A Large-Scale Human-Labeled Dataset for Complex and Cross-Domain Semantic Parsing and Text-to-SQL Task ⭐⭐⭐⭐⭐ EMNLP 2018, arXiv:1809.08887 Dataset: spider GitHub: github.com/taoyds/spider 一、论文速读 本文提出了 Text2SQL 方向的…

【机器学习】基于核的机器学习算法(Kernel-based Algorithms):原理,应用与优化

👀传送门👀 文章引言🔍🍀核函数的概念🚀基于核的算法原理💖基于核的算法应用🐟支持向量机(SVM)📕核主成分分析(KPCA) 🍀未…

创新实训2024.05.26日志:服务端接口实现——用户开启多个会话

1. 概念图 类似于Kimi,文心一言,chatGPT等市面上主流的大模型,我们的大模型也支持同一个用户的多个会话,并且提供支持联系上下文给出解答的能力。 2. 基于会话的对话 在langchain chatchat这个对langchain框架进行二次封装的第三…

汇编语言程序设计-5-流程转移与子程序

5. 流程转移与子程序 文章目录 5. 流程转移与子程序5.0 导学5.1 “转移”综述5.2 操作符offset5.3 jmp指令5.4 其他转移指令-jcxz、loop5.5 call指令和ret指令5.6 call和ret的配合使用5.7 mul指令5.8 汇编语言的模块化程序设计5.9 寄存器冲突的问题-子程序标准框架5.10 标志寄存…

postgresql|数据库|闪回插件e-maj的部署和使用

前言: E-Maj 是 PostgreSQL 数据库的一个扩展插件,它的全称为 "Elementary Majordomo"。这个扩展的主要功能是为数据库中的表集提供细粒度的写入日志记录和时间旅行能力。这意味着使用 E-Maj 的用户可以在数据库的特定子集上实现事务的回滚&a…

python列表元素的增减之道:删除篇

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、前言 二、删除元素的基本方法 1. 使用remove()方法 2. 使用pop()方法 3. 使用del语句…

mars3d的V2版本的Video2D与V3版本的Video2D实现数据快速迁移

场景: 目前是v2和v3的两个相机视角的不同格式,在Mars3d的V2的旧数据想可以快速迁移到V3版本。 V2版本的数据: {"camera": {"fov": 1.0471975511965976,"dis": 20,"stRotation": 0,"showFrust…

第 33 次CCF认证

1. 词频统计 题目描述 样例输入 代码 #include <bits/stdc.h>using namespace std;int main() {int n,m;cin>>n>>m;vector<int> ans1(m,0),ans2(m,0);while (n --) {int t;cin>>t;vector<int> vis(m1,0);for (int i 1;i < t;i ) {i…

这样的直男程序员,活该你单身一万年!

#分享下相亲时遇到过哪些奇葩现象# 这样的直男程序员&#xff0c;活该你单身一万年&#xff01; 在丛丛脱单小程序上相亲&#xff0c;遇到一个程序员妹纸&#xff0c;于是有了如下的真实故事&#xff1a; 妹子说她是程序员来着&#xff0c;想着我也是程序员&#xff0c;就想交…