当前位置: 首页 > news >正文

设计模式——单例模式(1)

一、写在前面

  • 设计模式有23种,每一篇是一种模式,从简单到难,第一篇从最简单的单例模式试试水
  • 创建型模式
    • 单例模式
    • 工厂方法模式
    • 抽象工厂模式
    • 原型模式
    • 建造者模式
  • 结构型模式
  • 行为型模式

二、介绍

  • 单例模式是指一个类只能创建出一个对象,比如数据库连接池、日志记录。在开发中用到的很多
  • 单例设计模式分类成两种:
    • 饿汉式:类加载就会导致该单实例对象被创建
    • 懒汉式:类加载不会导致该单实例对象被创建,而是首次使用该对象时才会创建
  • 在使用单例模式时,要明确或注意以下几点
    • (1)将构造方法写成私有的,防止外部调用构造方法
    • (2)应该在类的属性中修饰成static,我一开始觉得这只是为了确保实例能通过类名在全局访问,但是在研究了Java虚拟机之后,其实这么做最核心的原因是:static变量会随着类被初次访问而初始化,并且在整个程序的生命周期中,这个对象不会被动销毁。这对于单例模式来说至关重要,因为它保证了单例对象在程序运行期间的唯一性和持久性。

三、饿汉式

1、饿汉式一

/**
* 饿汉式
* 静态变量创建类的对象
*/
public class Singleton {
//私有构造方法
private Singleton() {}
//在成员位置创建该类的对象
private static Singleton instance = new Singleton();
//对外提供静态方法获取该对象
public static Singleton getInstance() {
return instance;
}
}
  • 该方式在成员位置声明Singleton类型的静态变量,并创建Singleton类的对象instance。
  • instance对象是随着类的加载而创建的。如果该对象足够大的话,而一直没有使用就会造成内存的浪费。
  • 还有一种方法是在static块中new,但是根据JVM类加载器的执行顺序,本质上效果并没有区别,就不放代码了~

2、饿汉式二(枚举,比较直观就不解释了)

public enum Singleton {
INSTANCE;
}

四、懒汉式

  • 在使用懒汉式创建时,需要提供一个getInstance接口(public),需要使用这个类的对象时,对其进行调用

1、懒汉式一(线程不安全)

public class Singleton {
//私有构造方法
private Singleton() {}
//在成员位置创建该类的对象
private static Singleton instance;
//对外提供静态方法获取该对象
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
  • 为什么线程不安全呢?
    • 如果有两个线程A和B同时调用这个方法,A和B同时发现instance为null,就会都new一个对象,造成的结果就是最终有两个对象,违反了单例模式

2、懒汉式2(双重检查锁,单例模式的最优解!)

public class Singleton {//私有构造方法private Singleton() {}private static volatile Singleton instance;//对外提供静态方法获取该对象public static Singleton getInstance() {//第一次判断,如果instance不为null,不进入抢锁阶段,直接返回实际if(instance == null) {synchronized (Singleton.class) {//抢到锁之后再次判断是否为空if(instance == null) {instance = new Singleton();}}}return instance;}
}
  • 此方法使用的是饿汉式,所以不存在内存浪费的问题
  • 首先,我们假设有A、B两个线程。进入getInstance方法后,需要判断是否创建对象,如果没有创建,我们假设A和B同时进入。
  • 然后,我们用字节码文件做锁对象,A和B只有一个线程能拿到锁(假设A先拿到了),另一个(B)在自旋等待。
  • 接着,A进入之后发现单例对象为null,会正常new一个对象出来,然后释放锁
  • 接下来,B因为此时在自旋等待,当A释放锁之后,B进入了,但单例对象此时已经不为null了,就不会执行new
  • 最后,两个线程也只会创建一个单例对象,并且没有空间浪费的问题
  • "volatile"是一个关键字,用于确保多线程环境下的变量可见性和禁止指令重排序优化。当一个变量被声明为volatile时,它意味着:
    • 可见性:当一个线程修改了一个volatile变量的值,新值对其他线程是立即可见的。这确保了线程之间共享变量的状态始终是最新的。
    • 禁止指令重排序:volatile关键字可以禁止JVM的指令重排序优化,从而确保程序执行的顺序性。

相关文章:

设计模式——单例模式(1)

一、写在前面 设计模式有23种,每一篇是一种模式,从简单到难,第一篇从最简单的单例模式试试水创建型模式 单例模式工厂方法模式抽象工厂模式原型模式建造者模式 结构型模式行为型模式 二、介绍 单例模式是指一个类只能创建出一个对象&#…...

剧本杀小程序:提升玩家游戏体验,带动经济效益

剧本杀作为一个新兴游戏方式,能够满足年轻人的社交需求,让大众体验到不太一样的人生,在角色中进行演绎。这种独特的游戏模式吸引了众多的年轻玩家,由此,剧本杀行业进入了爆发期。 如今,在科技的不断创新下…...

Linux系统通过编辑crontab来设置定时任务---定时关机

在Linux系统中,crontab 是用来设置周期性被执行的指令的守护进程。通过编辑 crontab,您可以安排定时任务,比如定时关机、定时备份文件、定时运行脚本等。以下是如何编辑 crontab 来设置定时任务的步骤: 打开终端:您可以…...

Mac电脑word文档误删,4个方法快速恢复

对于使用Mac的用户来说,丢失重要的Word文档可能会为学习或工作带来严重的影响。不过,幸运的是,关于mac word 文档恢复方法还是有很多的,通常帮助Mac用户轻松找回丢失的word文档。接下来,小编将介绍一些在Mac上恢复丢失…...

threejs-基础材质设置

一、介绍 主要内容:基础材质(贴图、高光、透明、环境、光照、环境遮蔽贴图) 主要属性: side: three.DoubleSide, //设置双面 color: 0xffffff, //颜色 map: texture, //纹理 transparent: true, // 透明度 aoMap: aoTexture, //ao贴图 aoMapIntensity: 1…...

【大模型开发】AI提示词框架:解锁ICIO、CRISPE、BROKE和RASCEF的强大潜力

作为一名经验丰富的程序员,您是否曾感到在与AI助手交互时难以获得理想的输出?本文将为从事AI开发或经常使用AI工具的技术人员介绍四个强大的AI提示词框架:ICIO、CRISPE、BROKE和RASCEF。这些框架能帮助您更有效地与AI模型沟通,提高工作效率。 1. ICIO框架:简洁而有力 IC…...

Rust学习如何更有信心?

关于如何学习Rust,在Hacker News上有一篇非常火的教程,作者通过自己的Rust学习经历,向大家指出了一条如何学习Rust的路径。 学习一门编程语言必不可少的是阅读技术书籍和编写代码,要想掌握Rust,两者的交替学习至关重要…...

3个简单易懂的方法,教你马上掌握excel表格数据打印技巧

在EXCEL表格里制作表格后,表格的数据有可能不正好是一页,如果就这样打印出来,数据有可能不完整,表格也不美观,还浪费纸张,那么如何将表格打印在一张纸上呢?下面小编为你介绍几种方法和解决方案&…...

dbt 增量策略模型实战教程

上文我们介绍了增量策略的理论知识,本文结合实际场景介绍如何合理利用增量策略,内容包括应用场景、常见问题及解决方案。 应用场景 增量模型是定义如何增量向数据模型添加数据的有效方法——假设我们有描述信用卡交易的数据表——我们创建DBT模型&#…...

【含文档】基于Springboot+Android的校园论坛系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…...

Go版数据结构 -【8.4 快速排序】

8.4 快速排序 快速排序是一种分而治之的排序算法。它通过随机选择一个基准元素,将数组分为两部分。 一部分比基准元素小,另一部分比基准元素大,之后对两部分排序。 快速排序以其平均情况下的 O(n log n) 时间复杂度和良好的性能而广泛应用…...

达梦DBLINK访问ORACLE配置方法

目录 1、概述 2、测试环境 3、语法简介 4、配置访问DM的DBLINK 5、配置访问ORACLE的DBLINK 5.1 通过OCI配置 5.2 通过ODBC配置 1、概述 本文介绍了达梦DBLINK的配置方法。有3部分内容,1)达梦访问到达梦的配置方法;2)通过OC…...

基础知识1

目录 1、gcd最大公因数 2、最小公倍数 3、素数问题 ①简单数学求法 ②素数筛 ③线性筛 1、gcd最大公因数 int gcd(int a,int b){return b0?a:gcd(b,a%b);} 做题过程中,如果数据太大,需要边做边对分子分母进行约分 2、最小公倍数 int a,b;scanf(&…...

网页前端开发之Javascript入门篇(9/9):对象

Javascript对象 什么是对象? 答:其概念跟 Python教程 的字典基本相似,虽然存有一些差异,不过对于目前的教程来讲可以忽略。 下面是对象的语法: var aaa {"弓" : "张","木" : "李",&…...

Oracle RAC IPC Send timeout detected问题分析处理

一、报错信息 今天在进行数据库巡检时,在集群节点1发现了IPC相关报错信息: 2024-10-10T10:22:06.84631708:00 IPC Receiver dump detected. Sender instance 2 Receiver pnum 277 ospid 377527 [oraclezxsszpt-sjkfwq1 (PPA6)], pser 124403 2024-10-1…...

QT 实现QMessageBox::about()信息自定义显示

这是我记录Qt学习过程的第四篇心得文章,主要是方便自己编写的应用程序显示“关于信息”,对QMessageBox::about()输入信息进行规范,可以设置应用程序名称,通过定义宏从pro文件获取应用程序版本号,以及编译程序的QT版本、…...

(C++进阶)C++20

目录 一、概述 二、新特性 1. 模块(Modules)功能 2. 概念(Concepts)功能 3. 范围(Ranges)功能 4. 协程(Coroutines)功能 5. 三路比较运算符(Spaceship Operator&a…...

【常用的安装破解版指令】MAC安装破解版软件显示文件损坏时

MAC安装破解版软件显示文件损坏时 复制以下命令粘贴到终端后 sudo xattr -rd com.apple.quarantine 打开Finder(访达),点击左侧的 应用程序,将应用拖进终端中,然后按键盘的回车键(return)&…...

【QT Quick】定时器和线程:定时器Timer

在现代用户界面开发中,动态更新内容、处理定时任务或异步任务是常见的需求,尤其在复杂应用中可能会遇到界面阻塞的问题。在 Qt Quick 中,定时器(Timer)和多线程是两种主要的解决方案,用于避免这种阻塞现象。…...

【NIO基础】NIO(非阻塞 I/O)和 IO(传统 I/O)的区别,以及 NIO 的三大组件详解

目录 1、NIO 2、NIO 和 IO 的区别 1. 阻塞 vs 非阻塞 2. 一个线程 vs 多个连接 3. 面向流 vs 面向缓冲 4. 多路复用 3、Channel & Buffer (1)Channel:双向通道 (2)Buffer:缓冲区 (3)ByteBuffer&#xff…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...

大话软工笔记—需求分析概述

需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

Selenium常用函数介绍

目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...