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

八种单例模式

文章目录

    • 1.单例模式基本介绍
        • 1.介绍
        • 2.单例模式八种方式
    • 2.饿汉式(静态常量,推荐)
        • 1.基本步骤
          • 1.构造器私有化(防止new)
          • 2.类的内部创建对象
          • 3.向外暴露一个静态的公共方法
        • 2.代码实现
        • 3.优缺点分析
    • 3.饿汉式(静态代码块,推荐)
        • 1.代码实现
        • 2.优缺点分析
    • 4.懒汉式(线程不安全,实际开发不要使用)
        • 1.代码实现
        • 2.优缺点分析
    • 5.懒汉式(线程安全,同步方法,实际开发不推荐使用)
        • 1.代码实现
        • 2.优缺点分析
    • 6.懒汉式(线程安全,同步代码块,解决不了同步问题)
        • 1.介绍
        • 2.优缺点分析
    • 7.双重检查(推荐使用)
        • 1.代码实现
        • 2.关于volatile关键字
          • 使用 `volatile` 的常见场景
          • 复合操作的限制
          • 总结
        • 3.优点分析
    • 8.静态内部类实现(推荐使用)
        • 1.前置知识
          • 1.外部类被装载,静态内部类不会被装载
          • 2.当调用静态内部类的属性时,静态内部类会被装载且只会被装载一次
          • 3.在类装载的时候是线程安全的
        • 2.代码实现
        • 3.优点分析
    • 9.枚举实现(推荐使用)
        • 1.代码实现
        • 2.优缺点分析
    • 10.单例模式总结
        • 1.Runtime就使用了饿汉式的单例模式
        • 2.注意事项和细节

1.单例模式基本介绍

1.介绍

image-20240526192046799

2.单例模式八种方式

image-20240526192132094

2.饿汉式(静态常量,推荐)

1.基本步骤
1.构造器私有化(防止new)
2.类的内部创建对象
3.向外暴露一个静态的公共方法
2.代码实现
package com.sun.type1;/*** Description: 单例模式饿汉式(静态变量)* @Author sun* @Create 2024/5/26 19:28* @Version 1.0*/
public class Singleton01 {public static void main(String[] args) {// 通过公有的静态方法,获取实例Singleton instance = Singleton.getInstance();Singleton instance1 = Singleton.getInstance();System.out.println(instance1 == instance); // 返回的是true}
}class Singleton {// 1.构造器私有化private Singleton() {}// 2.本类的内部创建对象实例private final static Singleton instance = new Singleton();// 3.暴露一个公有的静态方法,返回实例对象public static Singleton getInstance() {return instance;}
}

image-20240526194327006

3.优缺点分析

image-20240526194535444

3.饿汉式(静态代码块,推荐)

1.代码实现
package com.sun.type1;/*** Description: 单例模式饿汉式(静态代码块)* @Author sun* @Create 2024/5/26 19:49* @Version 1.0*/
public class Singleton02Test {public static void main(String[] args) {// 通过公有的静态方法,获取实例Singleton02 instance = Singleton02.getInstance();Singleton02 instance1 = Singleton02.getInstance();System.out.println(instance1 == instance); // 返回的是true}
}class Singleton02 {// 1.构造器私有化private Singleton02() {}// 2.本类的内部有一个静态属性private static Singleton02 instance;// 3.使用静态代码块为静态属性初始化static {instance = new Singleton02();}// 4.暴露一个公有的静态方法,返回实例对象public static Singleton02 getInstance() {return instance;}
}
2.优缺点分析

image-20240526200000545

4.懒汉式(线程不安全,实际开发不要使用)

1.代码实现
package com.sun.type3;/*** Description: 单例模式懒汉式(线程不安全)* @Author sun* @Create 2024/5/26 20:02* @Version 1.0*/
public class Singleton03Test {public static void main(String[] args) {Singleton instance = Singleton.getInstance();Singleton instance1 = Singleton.getInstance();System.out.println(instance1 == instance);}
}class Singleton {// 1.构造器私有化private Singleton() {}// 2.静态属性,存放本类对象private static Singleton instance;// 3.静态的公有方法,当使用到该方法时才会去创建instancepublic static Singleton getInstance() {// 当静态属性没有被赋值的时候再去创建if (instance == null) {instance = new Singleton();}// 如果这个静态属性被初始化过了,就直接返回,保证是单例的return instance;}
}
2.优缺点分析

image-20240526201118772

5.懒汉式(线程安全,同步方法,实际开发不推荐使用)

1.代码实现
package com.sun.type4;/*** Description: 单例模式懒汉式(线程安全,同步方法)* @Author sun* @Create 2024/5/26 20:15* @Version 1.0*/
public class Singleton04Test {public static void main(String[] args) {Singleton instance = Singleton.getInstance();Singleton instance1 = Singleton.getInstance();System.out.println(instance1 == instance);}
}class Singleton {// 1.构造器私有化private Singleton() {}// 2.静态属性,存放本类对象private static Singleton instance;// 3.静态的公有方法,当使用到该方法时才会去创建instance,使用synchronized实现线程安全public static synchronized Singleton getInstance() {// 当静态属性没有被赋值的时候再去创建if (instance == null) {instance = new Singleton();}// 如果这个静态属性被初始化过了,就直接返回,保证是单例的return instance;}
}
2.优缺点分析

image-20240526202034683

6.懒汉式(线程安全,同步代码块,解决不了同步问题)

1.介绍

image-20240526202352115

2.优缺点分析

image-20240526202512379

7.双重检查(推荐使用)

1.代码实现
package com.sun.type6;/*** Description: 双重检查* @Author sun* @Create 2024/5/26 20:15* @Version 1.0*/
public class Singleton06Test {public static void main(String[] args) {Singleton instance = Singleton.getInstance();Singleton instance1 = Singleton.getInstance();System.out.println(instance1 == instance);}
}class Singleton {// 1.构造器私有化private Singleton() {}// 2.静态属性,存放本类对象,使用volatile防止指令重排序private static volatile Singleton instance;// 3.静态的公有方法,当使用到该方法时才会去创建instancepublic static Singleton getInstance() {// 先检查一次静态属性是否为空,这样可以过滤掉一部分if (instance == null) {// 如果为空,则进入同步代码块创建对象,由于还是会有多个线程进来,所以在内部需要二次检查synchronized (Singleton.class) {// 在此完成双重检查if (instance == null) {instance = new Singleton();}}}// 如果这个静态属性被初始化过了,就直接返回,保证是单例的return instance;}
}
2.关于volatile关键字
使用 volatile 的常见场景
  1. 直接赋值

    • 设置标志位,如控制线程的开始或停止。
    • 单个配置值的更新,这个值被多个线程读取。

    例如,一个线程控制开关:

    public class TaskRunner implements Runnable {private volatile boolean stop = false;public void run() {while (!stop) {// 执行任务}}public void stop() {stop = true;}
    }
    
  2. 单一读取操作

    • 在这种情况下,volatile 保证了每次读取操作都从主内存中获取最新值,而不是从线程的本地缓存。
复合操作的限制

如果操作涉及到对变量的读取、修改和写回(如 a++),则 volatile 不能保证操作的原子性。这类操作需要使用 synchronizedjava.util.concurrent.atomic 包中的原子类。例如,对一个计数器进行增加操作:

public class Counter {private volatile int count = 0; // 这是错误的做法,对于 count++ 操作public void increment() {count++; // 这不是线程安全的}
}

在上面的代码中,count++ 操作实际上是三个步骤:读取 count 的当前值,增加 1,然后写回新值。这三个步骤不是原子操作,因此即使 count 被声明为 volatile,在多线程环境中也可能导致不正确的结果。

总结

总之,当你的需求仅限于确保多线程之间对单个变量直接赋值操作的可见性和有序性时,使用 volatile 是合适的。然而,对于需要多个步骤或基于当前值的修改的操作,你需要使用更强的同步机制。

3.优点分析

image-20240526204442702

8.静态内部类实现(推荐使用)

1.前置知识
1.外部类被装载,静态内部类不会被装载
2.当调用静态内部类的属性时,静态内部类会被装载且只会被装载一次
3.在类装载的时候是线程安全的
2.代码实现
package com.sun.type7;/*** Description: 单例模式(静态内部类实现)* @Author sun* @Create 2024/5/26 20:51* @Version 1.0*/
public class Singleton07Test {public static void main(String[] args) {Singleton instance = Singleton.getInstance();Singleton instance1 = Singleton.getInstance();System.out.println(instance1 == instance);}
}class Singleton {// 1.构造器私有化private Singleton() {}// 2.一个静态内部类,该类有一个静态属性,存放外部类的对象private static class SingletonInstance {public static final Singleton INSTANCE = new Singleton();}// 3.静态的公有方法,当要使用时调用内部类的静态属性,此时静态内部类会被装载,且只会被装载一次public static Singleton getInstance() {return SingletonInstance.INSTANCE;}
}
3.优点分析

image-20240526210255702

9.枚举实现(推荐使用)

1.代码实现
package com.sun.type8;/*** Description: 单例模式(静态内部类实现)* @Author sun* @Create 2024/5/26 20:51* @Version 1.0*/
public class Singleton08Test {public static void main(String[] args) {Singleton instance = Singleton.INSTANCE;Singleton instance2 = Singleton.INSTANCE;System.out.println(instance2 == instance);}
}enum Singleton {// 这个就相当于调用无参构造创建了这个类的一个对象,可以实现单例模式INSTANCE;
}
2.优缺点分析

image-20240526210742011

10.单例模式总结

1.Runtime就使用了饿汉式的单例模式

image-20240526211234759

2.注意事项和细节

image-20240526211508150

相关文章:

八种单例模式

文章目录 1.单例模式基本介绍1.介绍2.单例模式八种方式 2.饿汉式(静态常量,推荐)1.基本步骤1.构造器私有化(防止new)2.类的内部创建对象3.向外暴露一个静态的公共方法 2.代码实现3.优缺点分析 3.饿汉式(静态…...

禅道密码正确但是登录异常处理

禅道密码正确,但是登录提示密码错误的异常处理 排查内容 # 1、服务器异常,存储空间、数据库异常 # 2、服务异常,文件丢失等异常问题定位 # 1、df -h 排查服务器存储空间 # 2、根据my.php排查数据库连接是否正常 # 3、修改my.pho,debugtrue…...

Go微服务: Nacos的搭建和基础API的使用

Nacos 概述 文档:https://nacos.io/docs/latest/what-is-nacos/搭建:https://nacos.io/docs/latest/quickstart/quick-start-docker/有很多种搭建方式,我们这里使用 docker 来搭建 Nacos 的搭建 这里,我们选择单机模式&#xf…...

基于Hadoop的城市公共交通大数据时空分析

基于Hadoop的城市公共交通大数据时空分析 “Spatio-temporal Analysis of Urban Public Transportation Big Data based on Hadoop” 完整下载链接:基于Hadoop的城市公共交通大数据时空分析 文章目录 基于Hadoop的城市公共交通大数据时空分析摘要第一章 引言1.1 研究背景1.2 …...

DNS服务的部署与配置(2)

1、dns的安装及开启 dnf install bind.x86_64 -y #安装 #Berkeley Internet Name Domain (BIND) systemctl enable --now named #启用dns服务,服务名称叫named firewall-cmd --permanent --add-servicedns #火墙设置 firewall-cmd --reload …...

MySql--SQL语言

目录 SQl---DDL 结构定义 创建、删除 数据库 代码 运行 设计表 数据类型 整数 浮点数 主键 约束 主键自增长 默认值 字段注释 创建、删除 表 代码 运行 代码 代码 运行 SQL---DML 数据操纵 插入数据 代码 运行 代码 运行 代码 运行 代码 …...

【网络安全】2030年十大新兴网络安全威胁

欧盟网络安全局(ENISA)已发布了一份全面的清单,列出了预计到2030年将影响数字领域的十大新兴网络安全威胁。 该预测是为期八个月的广泛研究的成果,融合了ENISA前瞻专家小组、CSIRTs网络以及欧盟CyCLONe专家的见解。 这项研究突显…...

python数据分析-CO2排放分析

导入所需要的package import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import datetime %matplotlib inline plt.rcParams[font.sans-serif] [KaiTi] #中文 plt.rcParams[axes.unicode_minus] False #负号 数据清洗…...

2024宝藏工具EasyRecovery数据恢复软件免费版本下载

在这个数字化的时代,数据已经成为我们生活中的重中之重。无论是工作中的重要文件,还是手机中珍贵的照片,我们都依赖着这些数据。然而,数据丢失的情况时有发生,可能是误删,可能是设备故障,更可能…...

【EventSource错误解决方案】设置Proxy后SSE发送的数据只在最后接收到一次,并且数据被合并

【EventSource错误解决方案】设置Proxy后SSE发送的数据只在最后接收到一次,并且数据被合并 出错描述 出错原因与解决方案 出错描述 SSE前后端一切正常,但是fetchEventSource 的onmessage回调函数只在所有流都发送完毕后,才会执行一次。 前…...

如何在linux命令行(终端)执行ipynb 文件。可以不依赖jupyter

1.安装 runipy pip install runipy 2.终端运行 runipy <YourNotebookName>.ipynb 在终端命令行执行shell脚本&#xff0c;&#xff08;也可以在crontab 中执行&#xff09;&#xff1a; (base) [recommendapp-0-5-B-006 script]$ cat run1.sh #!/bin/bashcd /home/recom…...

基于YOLOv8的车牌检测与识别(CCPD2020数据集)

前言 本篇博客主要记录在autodl服务器中基于yolov8实现车牌检测与识别&#xff0c;以下记录实现全过程~ yolov8源码&#xff1a;GitHub - ultralytics/ultralytics: NEW - YOLOv8 &#x1f680; in PyTorch > ONNX > OpenVINO > CoreML > TFLite 一、环境配置 …...

驱动开发之新字符设备驱动开发

1.前言 register_chrdev 和 unregister_chrdev 这两个函数是老版本驱动使用的函数&#xff0c;现在新的 字符设备驱动已经不再使用这两个函数&#xff0c;而是使用 Linux 内核推荐的新字符设备驱动 API 函数。 旧版本的接口使用&#xff0c;感兴趣可以看下面这个博客&#…...

【JMU】21编译原理期末笔记

本拖延症晚期患者不知不觉已经有半年没写博客了&#xff0c;天天不知道在忙什么。 乘着期末周前赶紧先把编译原理上传了&#xff0c;我记得我这科是86分&#xff0c;有点小遗憾没上90&#xff0c;但是总体不错。 链接&#xff1a;https://pan.baidu.com/s/1gO8pT7paHv1lkM_ZpkI…...

就业信息|基于SprinBoot+vue的就业信息管理系统(源码+数据库+文档)

就业信息管理系统 目录 基于SprinBootvue的就业信息管理系统 一、前言 二、系统设计 三、系统功能设计 1前台功能模块 2后台功能模块 4.2.1管理员功能 4.2.2学生功能 4.2.3企业功能 4.2.4导师功能 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设…...

一.架构设计

架构采用 ddd 架构&#xff0c;不同于传统简单的三层的架构&#xff0c;其分层的思想对于大家日后都是很有好处的&#xff0c;会给大家的思想层级&#xff0c;提高很多。 传统的项目 现有的架构 采取ddd架构&#xff0c;给大家在复杂基础上简化保留精髓&#xff0c;一步步进行…...

<学习笔记>从零开始自学Python-之-实用库篇(一)-pyscript

由Anaconda创建的PyScript是一项实验性的但很有前途的新技术&#xff0c;它使python运转时在支撑WebAssembly的浏览器中作为一种脚本言语运用。 每个现代常用的浏览器现在都支撑WebAssembly&#xff0c;这是许多言语&#xff08;如C、C和Rust&#xff09;能够编译的高速运转时…...

Vue项目中npm run build 卡住不执行的几种情况(实战版)

方法一 一&#xff1a;比较常见是镜像导致的原因 我们可以找到build/check-versions文件 将这段代码注释,重新运行就可以解决这个问题 if (shell.which(npm)) {versionRequirements.push({name: npm,currentVersion: exec(npm --version),versionRequirement: packageConfig.en…...

《Python源码剖析》之pyc文件

前言 前面我们主要围绕pyObject和pyTypeObject聊完了python的内建对象部分&#xff0c;现在我们将开启新的篇章—python虚拟机&#xff0c;将聚焦在python的执行部分&#xff0c;搞懂从“代码”到“执行”的过程。开启新的篇章之前&#xff0c;你也许会有一个疑惑&#xff1a;我…...

Python零基础-中【详细】

接上篇继续&#xff1a; Python零基础-上【详细】-CSDN博客 目录 十、函数式编程 1、匿名函数lambda表达式 &#xff08;1&#xff09;匿名函数理解 &#xff08;2&#xff09;lambda表达式的基本格式 &#xff08;3&#xff09;lambda表达式的使用场景 &#xff08;4&…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...