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

JAVA----单例模式

1.单例模式概念:

单例模式是一种设计模式,他的核心是确保一个类只有一个实例,单例模式主要有两种方式:饿汉式懒汉式

2.饿汉式

饿汉就是一个迫切的意思,类加载就会导致该单实例被创建

饿汉式第一种方式:

class Singleton{//在本类中创建本类对象private static Singleton instance=new Singleton();//提供一个公共的访问方式,让外界获取该对象public static Singleton getInstance(){return instance;}//私有构造方法private Singleton() {}
}

我们来对上面这个饿汉式解析一下:

1.私有构造方法,对于构造方法,我们使用private修饰,那么就保证了外界不能通过new这个操作来获取实例

2.饿汉,我们在类里面new一个实例,这个成员变量用private修饰,外界是无法获取的,同时static修饰了他,我们知道静态成员的初始化是在类加载的阶段触发的,所以只要这个类一被加载,那么我们的实例也就创建好了

3.getInstance方法,同样也是static修饰的,这是因为在本类中创建的实例是被static修饰的,普通的方法不能直接去访问,所以要将获取对象的这个方法也用static修饰,Singleton这个类不能构建实例,我们要想获取实例就只能类名.getInstance来获取到实例,然后通过这个实例去调用其他的方法或成员变量

饿汉式第二种方式:

class Singleton2{private static Singleton2 instance ;static {instance=new Singleton2();
}//对外提供方法获取该对象
public static Singleton2 getInstance(){return instance;
}//私有化的构造方法private Singleton2() {}
}

这种方式和第一种类似,只不过在本类当中创建对象的方式变成了使用静态代码块来创建

饿汉式第三种方式(枚举方式):

public enum Singleton3{instance;
}

 枚举方式实现单例模式是极力推荐的单例实现模式,因为枚举类型是线程安全的,并且只会装载一次,枚举实现的单例模式是唯一一种不会被破坏的单例实现模式

饿汉式总结说明:

这种方式在成员位置声明Singlleton类型的静态变量,并创建Singleton类的对象instance。instance对象会随着类的加载而创建。如果对象足够大1的话,而一直没有使用就会造成内存的浪费

2.懒汉式

类加载不会导致该单实例对象被创建,而是首次使用才会被创建

懒汉式第一种方式(线程不安全的):

class Singleton3{
//声明成员变量,不进行初始化private static Singleton3 instance;//提供获取对象的方法public static Singleton3 getInstance(){if(instance==null){instance=new Singleton3();}return instance;}//私有化的构造方法private Singleton3() {}
}

1.私有化的构造方法,是为了不让外界通过new创建多个实例

2.声明Singleton3类的成员变量不进行初始化

3.由于懒汉式是当我们用到时才去创建对象,所以在调用getinstance方法时才去创建

4.单列模式是一个类只能创建一个对象供外界使用,所以在调用getinstance方法时,getinstance方法内要做一次判断,判断一下instance这个变量是否为空,为空则创建这个实例,不为空则直接return

5.上面这种写法之所以线程不安全,是因为在多线程中,如果线程1调用getinstance这个方法执行到if语句,然后被操作系统调度到线程2,线程2也执行getinstance这个方法,线程2执行完毕后,又调度到线程1的if语句,这时执行new的操作,此时线程1和线程2都单独创建了一个SIngleton3的对象,这时就不满足单例模式只能创建一个对象的原则,所以就是线程不安全的

懒汉式第二种方式(线程安全的):

class Singleton3{private static Singleton3 instance;public static synchronized Singleton3 getInstance(){if(instance==null){instance=new Singleton3();}return instance;}private Singleton3() {}
}

懒汉式线程安全的,只需要在getinstance方法加上synchronized修饰就行了,这是给这个方法加上锁,锁对象是this,这样就保证了当一个线程执行getinstance方法时,不会被其他线程调度走

懒汉式第三种方式(双重检查锁):

为什么要使用双重检查锁,对于上述的两种懒汉式来说,getinstance方法大多数都是在进行读操作,而我们说,多线程里面,读操作是线程安全的,而写操作是线程不安全的,写操作只有new 对象赋值给instance,我们没必要让每个线程必须持有锁才能调用该方法,我们需要调整加锁的时机,来提高性能

class Singleton3{private static Singleton3 instance;public static synchronized Singleton3 getInstance(){if(instance==null){synchronized (Singleton3.class){if(instance==null){instance=new Singleton3();}}}return instance;}private Singleton3() {}
}

1.双重锁模式,只是在前面两种方式的基础上,将getinstance方法就行了修改,首先对instance进行判断,如果instance对象为空,那么就进行抢占锁操作,抢到锁之后,在进行一次判断,如果为空就进行new对象,如果第一次判断,instance不为空,那么说明instance已经创建,直接返回这个对象就行了

对双重检查锁的优化:

在多线程的情况下,双重检查锁,可能会出现空指针问题,出现问题的原因是JVM在实例化对象的时候会进行优化和指令重排序操作,要解决双重检查锁模式带来空指针异常的问题,只需要使用volatile关键字,volatile关键字可以保证可见性和有序性

class Singleton3{private static volatile Singleton3 instance;public static synchronized Singleton3 getInstance(){if(instance==null){synchronized (Singleton3.class){if(instance==null){instance=new Singleton3();}}}return instance;}private Singleton3() {}
}

添加volatile关键字之后,能够保证多线情况下的线程安全也不会有性能问题

懒汉式第四种方式(静态内部类):

静态内部类单例模式中实例有内部类创建,由于JVM在加载外部类的过程中,是不会加载静态内部类的,只有内部类的属性/方法被调用时才会被加载,并初始化其静态属性。静态属性由于被static修饰,保证只被实例化一次,并且严格保证实例化顺序

class Singleton4{
private static class SingletonHolder{
private final static Singleton4 INSTANCE=new Singleton4();    
}public static Singleton4 getInstance(){return SingletonHolder.INSTANCE;
}private Singleton4() {}
}

说明:

第一次加载SIngleton4类时不会去初始化INSTANCE,只有第一次调用getinstance,虚拟机加载SingletonHolde并初始化INSTANCE,这样不仅能保证线程安全,也能保证Singleton类的唯一性

静态内部类的方式在没有加锁的情况下,保证了线程安全,有没有影响性能和空间的浪费

相关文章:

JAVA----单例模式

1.单例模式概念: 单例模式是一种设计模式,他的核心是确保一个类只有一个实例,单例模式主要有两种方式:饿汉式与懒汉式 2.饿汉式 饿汉就是一个迫切的意思,类加载就会导致该单实例被创建 饿汉式第一种方式:…...

基于递推式最小二乘法的PMSM参数辨识MATLAB仿真模型

微❤关注“电气仔推送”获得资料(专享优惠) 模型简介 最小二乘法是一种回归估计法,适用于被辨识的参数与系统输出为线性关 系的情况。它是在一定数据量下,基于系统输出误差的平方和最小的准则对参 数进行辨识的方法。此模型通过…...

记录一次部署 k8s 集群无法启动

情况是这样的,k8s 集群(v1.31)所需要的组件已安装完成,通过 kubeadm init 已经安装部署成功,但是等几分钟,集群组件就一直在重启,查看日志是连接 etcd 超时,所以查看了 etcd 的日志&…...

Linux下MySQL8.x的编译安装与使用

Linux下MySQL的安装与配置 1. 安装环境初始化 1.1 查看是否安装过MySQL 如果使用rpm安装, 检查一下RPM PACKAGE rpm -qa | grep -i mysql # -i 忽略大小写 # 或者 yum list installed | grep mysql如果存在mysql-libs的旧版本包,显示如下 #存在 [rootlocalhost ~]…...

cpuinfo实践记录

py-cpuinfo 是一个用于获取 CPU 信息的 Python 库。它可以帮助你获取 CPU 的详细信息,如 CPU 型号、核心数、频率、缓存大小等。以下是对 py-cpuinfo 模块的详细介绍: 安装 你可以使用 pip 来安装 py-cpuinfo 库: pip install py-cpuinfo …...

【Java】ArrayList相关操作及其案例

ArrayList相当于集合&#xff0c;作为一种容器存储数据&#xff0c;与数组类似。不同的是&#xff0c;ArrayList中长度可变&#xff0c;而数组长度不可变。 ArrayList相关API 构造器 public ArrayList() 创建一个空的集合对象 ArrayList<String>arrnew ArrayList<>…...

手机pdf阅读器,用手机也能够阅读、编辑pdf文件

在日常的学习或办公过程中&#xff0c;PDF格式的文件是我们最常遇见的文件格式之一&#xff0c;那么为了更高效、便捷地处理这些文件&#xff0c;选择一款合适的PDF阅读器至关重要&#xff0c;可以帮助我们在阅读文件的同时还可以对文件进行适当编辑处理。今天小编给大家带来几…...

通过 Twitter Token 实现授权与操作

通过 Twitter Token 实现授权与操作 一、Twitter API 概览 1.1 Twitter API 简介 Twitter API 是 Twitter 公司提供的一种编程接口,它允许开发者访问 Twitter 的海量数据,包括用户信息、推文内容、关系网络等。通过这些接口,开发者可以创建应用程序,实现自动化的社交媒体…...

100个SSM框架(Spring + Spring MVC + MyBatis)毕业设计选题

100个SSM框架(Spring Spring MVC MyBatis)毕业设计选题 电子商务 综合性电子商务平台跨境电商管理系统社区团购平台二手商品交易网站农产品直销平台奢侈品鉴定与交易系统电子优惠券管理平台闪购秒杀系统个性化商品推荐系统多商户店铺管理平台 教育培训 在线教育课程平台智…...

STM32F1+HAL库+FreeTOTS学习17——事件标志组

STM32F1HAL库FreeTOTS学习17——事件标志组 1. 事件标志组1.1 事件标志组的的引入1.2 事件标志组简介1.3 事件标志组与队列、信号量的区别 2. 事件标志组下相关API函数2. 1 xEventGroupCreate()2. 2 xEventGroupCreateStatic()2. 3 vEventGroupDelete()2. 4 xEventGroupWaitBit…...

ElasticSearch基本概念

本文内容参考了田雪松老师编著的《Elastic Stack应用宝典》 对比关系型数据库 索引&#xff08;Index&#xff09;相当于库映射类型&#xff08;Mapping Type&#xff09;相当于表文档&#xff08;Document&#xff09;相当于行文档字段&#xff08;Field&#xff09;相当于列…...

fluent-ffmpeg操作MP3文件深入解析

软考鸭微信小程序 学软考,来软考鸭! 提供软考免费软考讲解视频、题库、软考试题、软考模考、软考查分、软考咨询等服务 引言 fluent-ffmpeg是一个功能强大的Node.js库&#xff0c;它为FFmpeg提供了一个流畅的接口。FFmpeg是一个著名的多媒体框架&#xff0c;以处理音频、视频和…...

做信创项目需要什么资质、信创产品认证标准?

信创项目需要企业具备一些特定的资质和认证&#xff0c;以证明其合规性和专业性。以下是做信创项目可能用到的一些资质&#xff1a; 1. 信息安全管理体系认证&#xff08;ISO27001&#xff09;&#xff1a;该认证可以证明企业已经建立了完善的信息安全管理体系&#xff0c;能够…...

Spring i18n国际化

从源码MessageSource的三个实现出发实战springi18n国际化 - 简熵 - 博客园 import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.MessageSource; import org.spri…...

基于stm32的楼宇照明控制系统设计

基于stm32的楼宇照明控制系统设计 项目说明一、绪论1.1 研究背景1.2 研究意义1.4 研究内容 二、系统方案设计2.1 微控制器方案选择2.2 信息检测模块方案选择2.3 WiFi模块选择2.4 终端显示2.5 WiFi无线通信实现方法 三、系统硬件电路图设计3.1 整体电路图设计3.2 主控制器设计3.…...

ESP32移植Openharmony外设篇(3)OLED屏

模块简介 产品介绍 OLED (Organic Light-Emitting Diode)&#xff1a;有机发光二极管又称为有机电激光显示&#xff0c;OLED显示技术具有自发光的特性&#xff0c;采用薄的有机材料涂层和玻璃基板&#xff0c;当有电流通过时&#xff0c;这些有机材料就会发光&#xff0c;而且…...

人工智能:未来生活与工作的变革力量

人工智能&#xff08;AI&#xff09;作为21世纪最具变革性的技术之一&#xff0c;正以前所未有的速度改变着我们的生活和工作方式。从医疗行业的突破性进展到企业运营的智能化&#xff0c;以及日常生活中各种智能产品的普及&#xff0c;人工智能正在成为现代社会不可或缺的一部…...

AI自动生成PPT哪个软件好?智能生成PPT不再熬夜做课件

大概这世上&#xff0c;都是职场牛马对“PPT”这三个字母的头痛反应最大吧&#xff01; 是的&#xff0c;就连各个年级段的老师也是很头痛——愁着怎样能在排版整齐的情况下&#xff0c;将必考知识点都呈现在PPT每一张幻灯片页面里...... 近期打听到用人工智能生成ppt课件&am…...

C# OOP面试题精选 面向新手/SOLID原则/设计模式++ 长期更新

1.整理目的 相当于0.1版本&#xff0c;旨在学习/提升/复习 关于面向对象模块的知识 目前&#xff0c;记录了一些比较容易混淆或者突然想不起的冷门内容 还有一些个人经过实战后总结的内容&#xff0c;其中还指明了很多实例和分析链接以更加方便地复习 【金山文档 | WPS云文…...

安全见闻(2)——开阔眼界,不做井底之蛙

内容预览 ≧∀≦ゞ 安全见闻二&#xff1a;Web程序构成与潜在漏洞声明导语前端语言及潜在漏洞前端语言前端框架与代码库代码库的概念和用途流行的JavaScript框架常见的代码库 前端潜在漏洞 后端语言及潜在漏洞常见后端语言协议问题后端潜在漏洞 数据库及潜在漏洞数据库分类数据…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...