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

Java 中实现单例模式

单例模式

单例模式,就是一个类在任何情况下绝对只有一个实例,并且提供一个全局访问点来获取该实例。
要实现单例,至少需要满足两个点:
  • 私有化构造方法,防止被外部实例化造成多实例问题
  • 提供一个静态方位作为全局访问点来获取唯一的实例对象
在 Java 里面,至少有 6 种方法来实现单例。

实现

第一种

第一种, 是最简单的实现,通过延迟加载的方式进行实例化,并且增加了同步 锁机制避免多线程环境下 的线程安全问题.
public class Singleton {private static  Singleton instance;private Singleton(){}public static  synchronized Singleton getInstance(){if (instance == null){instance=new Singleton();}return instance;}
}
但是这种加锁会造成性能问题,而且同步锁只有在第一次实例化的时候才产生作用,后续不需要。

第二种

第二种,通过双重检查锁的方式,减少了锁的范围来提升性能 

public class Singleton {private volatile static Singleton instance;private Singleton() {// 私有构造函数}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}

instance 使用 volatile 关键字修饰,以确保多线程环境下的可见性和有序性。

使用volatile关键字修饰instance变量,主要是为了保证在多线程环境下获取单例实例的可见性和有序性。具体来说:

  1. 可见性:当一个线程第一次访问getInstance()方法时,如果instancenull,那么该线程将进入同步块并创建实例。这个写操作对于其他线程来说是可见的,即它们将立即看到instance的新值。这就避免了在一个线程创建实例后,其他线程仍然看到instancenull的情况。

  2. 有序性:在双重检查锁中,由于编译器和处理器的优化行为,可能会发生指令重排序。如果没有使用volatile关键字修饰instance,那么在某些情况下,其他线程可能会看到指令重排后的顺序,从而导致单例实例的未完全初始化。而使用volatile修饰instance后,禁止了这种指令重排序优化,保证了实例的完整性。

第三种

第三种,通过饿汉式实现单例。这种方式在类加载的时候就触发了实例化,从而避免了多线程同步问题。 
public class Singleton {private static Singleton instance=new Singleton();private Singleton(){}public static  Singleton getInstance(){return instance;}}

第四种

第四种,通过在静态块里面实例化,而静态块是在类加载的时候触发执行的,所以也只会执行一
次。
public class Singleton {private static Singleton instance = null;static {instance=new Singleton();}private Singleton(){}public Singleton getInstance(){return instance;}}
上面两种方式,都是在类加载的时候初始化,没有达到延迟加载的效果,当然本身影响不大。

第五种

由于静态内部类只有调用静态内部类的方法,静态域,或者构造方法的时候才会加载静态内部类。
public class Singleton {private static class SingletonHolder{private static final Singleton INSTANCE=new Singleton();}private Singleton(){}public static final Singleton getInstance(){return SingletonHolder.INSTANCE;}
}
所以当 Singleton 被加载的时候不会初始化 INSTANCE,从而实现了延迟加载。

第六种

我们还可以使用枚举类来实现。
public enum Singleton {INSTANCE;// 添加其他成员变量和方法public void doSomething() {// 单例实例的操作}
}
这种写法既能避免多线程同步问题,又能防止反序列化重新创建新对象,也是一个比较好的方案。

总结

我认为大体分为 3 种方式来实现单例:
  • 第一种是通过双重检查锁的方式,它是一种线程安全并且是延迟实例化的方式,但是因为加锁,所以会有性能上的影响。
  • 第二种是通过静态内部类的方式实现,它也是一种延迟实例化,由于它是静态内部类,所以只会使用的时候加载一次,不存在线程安全问题。
  • 第三种是通过枚举类的方式实现,它既是线程安全的,又能防止反序列化导致破坏单例问题
多线程、克隆、反序列化、反射,都有可能会造成单例的破坏。而我认为,通过枚举的方式实现单例,是能够解决所有可能被破坏的情况。

相关文章:

Java 中实现单例模式

单例模式 单例模式,就是一个类在任何情况下绝对只有一个实例,并且提供一个全局访问点来获取该实例。 要实现单例,至少需要满足两个点: 私有化构造方法,防止被外部实例化造成多实例问题 提供一个静态方位作为全局访问点…...

标签页的使用

目录 1、引用TabSheet.h和TabSheet.cpp文件: 2、主窗口添加标签页: (1)、标签页的创建和属性更改 (2)、添加俩个标签页的类 (3)、主窗口添加成员变量 (4&#xff09…...

新一代开源语音库CoQui TTS冲到了GitHub 20.5k Star

Coqui TTS 项目介绍 Coqui 文本转语音(Text-to-Speech,TTS)是新一代基于深度学习的低资源零样本文本转语音模型,具有合成多种语言语音的能力。该模型能够利用共同学习技术,从各语言的训练资料集转换知识,来…...

CSS 效果:多列文字,第一行对齐,flex方式元素被挤压

如图效果&#xff1a;2列&#xff0c;第一列只有一行&#xff0c;第二列多行。要求第一行对齐 实现&#xff1a;使用flex 如果不配置flex-shrink的话&#xff0c;第一列会被挤压 给第一列&#xff1a;备注配置压缩属性&#xff1a; flex-shrink&#xff1a;0。 <!DOCTYPE…...

优维低代码实践:片段

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…...

【计算机网络】第一章、计算机网络体系结构

1.1计算机网络的组成与分类 1.计算机网络的组成 从不同的角度来看内容从组成上看硬件、软件、协议从工作方式上岸边缘部分、核心部分从功能上看通信子网、资源子网 2.计算机网络的分类 角度内容分布范围广域网、城域网、局域网、个域网传输技术广播式网络、点对点网络拓扑结…...

vr火灾逃生安全科普软件开展消防突击教育安全有效

VR火灾逃生自救虚拟体验是一种利用虚拟现实技术来模拟火灾逃生自救场景的教育工具。以下是这个体验的几个优点&#xff1a;VR消防安全体验馆的出现&#xff0c;为城市的安全教育开辟了新的途径。这种创新的体验方式&#xff0c;能够让市民在模拟的火灾场景中学习并掌握消防安全…...

Kafka SASL认证授权(五)ACL源码解析

Kafka SASL认证授权(五)ACL源码解析。 官网地址:https://kafka.apache.org/ 一、ACL检查流程解析 一起看一下kafka server的启动与监听流程: Kafka -> KafkaServer -> SocketServer、KafkaRequestHandler 其中KafkaServer做相关的初始化,包括SocketServer 与 han…...

logback-spring.xml 中根据不同的业务表示,分类打印到不同的文件夹、时区动态设置

logback-spring.xml 中根据不同的业务表示&#xff0c;分类打印到不同的文件夹、时区动态设置 logback-spring.xml 完整配置 <?xml version"1.0" encoding"UTF-8"?> <configuration debug"false" scan"true" scanPeriod&…...

linux系统编程之一

1&#xff09;fcntl的使用方法 fcntl作用:可以用fcntl函数改变一个已打开的文件属性而不必重新打开文件&#xff1b; 堆排序是完全二叉树&#xff0c;但不是排序二叉树&#xff1b; 排序二叉树要求兄弟节点之间有大小关系&#xff0c;比如说左小右大&#xff1b; 堆排序仅要求…...

【LeetCode】《LeetCode 101》第十三章:链表

文章目录 13.1 数据结构介绍13.2 链表的基本操作206. 反转链表&#xff08;简单&#xff09;21. 合并两个有序链表&#xff08;简单&#xff09;24.两两交换链表中的节点&#xff08;中等&#xff09; 13.3 其它链表技巧160. 相交链表&#xff08;简单&#xff09;234. 回文链表…...

Electron webview 内网页 与 preload、 渲染进程、主进程的常规通信 以及企业级开发终极简化通信方式汇总

Electron 嵌入的页面中注入的是 preload.js 通过在标签中给 prelaod赋值&#xff0c;这里提到了 file://前缀&#xff0c;以及静态目录 static 怎么获取 实际代码&#xff0c;其中__static就是我们存放静态文件的地方&#xff0c;这个 static 是 electron 源代码根目录下的文件…...

AI人工训练师,提升外呼机器人的运营效果

外呼机器人是企业客服和营销的重要工具&#xff0c;外呼机器人可以通过语音识别和语音合成技术&#xff0c;自动拨打电话并进行客户服务和营销推广等工作。由于外呼机器人错误识别和理解偏差容易影响外呼效果&#xff0c;许多外呼机器人厂商选择通过AI人工训练师的技术手段来提…...

nginx正向代理、反向代理、负载均衡(重中之重)

nginx中有两种代理方式&#xff1a; 七层代理&#xff08;http协议&#xff09; 四层代理&#xff08;基于tcp或udp的流量转发&#xff09; 一、七层代理 原理&#xff1a;客户端请求代理服务器&#xff0c;由代理服务器转发客户端的http请求&#xff0c;转发到内部的服务器…...

MySQl_2

目录 函数 一.字符串函数 二.数值函数 三.日期函数 四.流程控制函数 约束 多表查询 多表关系 一.内连接 二.外连接 三.自连接 四.联合查询 五.子查询 标量子查询 列子查询 行子查询 表子查询 函数 一.字符串函数 二.数值函数 SELECT LPAD(FLOOR(RAND()*1000000),…...

使用Filter AND Interceptor校验等录(全网独一份,机不可失)

说明&#xff1a;基于spring boot进行的校验 1.熟悉如何使用jwt令牌。&#xff08;不会的看这里&#xff1a;带你领略JWTl令牌的魅力&#xff01;&#xff01;&#xff01;-CSDN博客&#xff09; Filter和Interceptor共用文件&#xff1a;&#xff08;可以仿照&#xff0c;根据…...

ubuntu20.04安装FTP服务

安装 sudo apt-get install vsftpd# 设置开机启动并启动ftp服务 systemctl enable vsftpd systemctl start vsftpd#查看其运行状态 systemctl status vsftpd #重启服务 systemctl restart vsftpdftp用户 sudo useradd -d /home/ftp/ftptest -m ftptest sudo passwd ftptest…...

MyBatisPlus(二十)防全表更新与删除

说明 针对 update 和 delete 语句&#xff0c;阻止恶意的全表更新和全表删除。 实现方式 配置BlockAttackInnerInterceptor拦截器 代码 package com.example.core.config;import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.p…...

14.9 Socket 高效文件传输

网络上的文件传输功能也是很有必要实现一下的&#xff0c;网络传输文件的过程通常分为客户端和服务器端两部分。客户端可以选择上传或下载文件&#xff0c;将文件分块并逐块发送到服务器&#xff0c;或者从服务器分块地接收文件。服务器端接收来自客户端的请求&#xff0c;根据…...

第二节 threejs简单案例

1. 创建3D场景 // 创建3D场景对象Scene const scene new THREE.Scene();// 更改场景背景颜色 scene.background new THREE.Color(#F5F5F5);2. 创建透视投影相机 // 实例化一个透视投影相机对象 const camera new THREE.PerspectiveCamera();相机位置 // 根据需要设置相机…...

基于AVR单片机的无线图像侦检系统:从硬件选型到软件实现

1. 项目概述与核心价值最近在整理过去的项目资料&#xff0c;翻到了一个挺有意思的老项目——基于Atmel AVR单片机的无线图像侦检系统。虽然现在STM32、ESP32满天飞&#xff0c;各种高性能MCU和无线模块层出不穷&#xff0c;但这个项目在当年&#xff08;以及现在某些特定场景下…...

别再死记硬背了!用NestJS + TypeORM实战‘用户-标签’系统,搞懂OneToMany和ManyToOne

NestJS TypeORM实战&#xff1a;构建高可维护的用户标签系统 在开发内容管理平台时&#xff0c;用户与标签的关联关系是典型的多对一建模场景。本文将带你从零实现一个基于NestJS和TypeORM的生产级用户标签系统&#xff0c;重点解析OneToMany和ManyToOne在实际项目中的最佳实践…...

别再乱配了!RuoYi-Vue-Plus中Sa-Token的activity-timeout与timeout到底啥区别?一个例子讲透

RuoYi-Vue-Plus中Sa-Token双超时机制&#xff1a;从业务场景到源码的深度实践 在基于Spring Boot的企业级开发中&#xff0c;会话管理一直是安全架构的核心环节。当我第一次在RuoYi-Vue-Plus项目中集成Sa-Token时&#xff0c;配置文件中那对看似相似的参数——activity-timeout…...

STM32F103移植FreeRTOS实战:从零构建多任务系统

1. 项目概述&#xff1a;为什么要在STM32F103上跑RTOS&#xff1f; 如果你玩过一阵子STM32&#xff0c;特别是经典的“蓝桥杯”神板——STM32F103C8T6&#xff0c;那你大概率已经习惯了在 main 函数里写一个 while(1) 大循环&#xff0c;里面塞满了各种 HAL_Delay 和状态…...

告别卡顿!用华为云ECS搭建eNSP Pro大型网络实验的保姆级避坑指南

华为云ECS部署eNSP Pro全流程性能优化实战 当你在本地PC上尝试运行包含20台NE路由器的复杂拓扑时&#xff0c;风扇狂转的噪音和逐渐卡死的界面是否让你抓狂&#xff1f;作为一位曾经被32GB内存工作站折磨过的网络工程师&#xff0c;我完全理解这种痛苦。直到发现华为云ECS这个&…...

深入PHY芯片:从88E1512的Loopback模式理解千兆以太网PCS/PMA/PMD分层

深入解析88E1512 PHY芯片&#xff1a;用环回模式透视千兆以太网物理层架构 在硬件网络调试的深水区&#xff0c;当常规的软件工具无法定位链路故障时&#xff0c;工程师需要一把能够解剖物理层数据流的"手术刀"。Marvell 88E1512这款高度集成的千兆以太网PHY芯片&…...

【习题02】打印菱形

题目&#xff1a; 用C语言在屏幕上输出以下图案&#xff1a;1、题目分析&#xff1a; 这道题目需要打印一个菱形&#xff0c;经过分析可得每一行就是打印空格和*。 经过观察可得&#xff1a; 第一行&#xff1a;6个空格 1个*第二行&#xff1a;5个空格 3个*第三行&#xff1a;4…...

2025_NIPS_Team-PSRO for Learning Approximate TMECor in Large Team Games via Cooperative Reinforce...

文章核心总结与翻译 一、主要内容 本文聚焦双人零和团队博弈(如桥牌、足球),针对现有算法要么仅适用于小型博弈且有博弈论保证,要么能扩展到大型博弈但缺乏理论保证的问题,提出了两种基于策略空间响应预言机(PSRO)的改进算法,旨在高效学习近似团队协调最大最小均衡(…...

企业级应用如何利用Taotoken的容灾与路由能力保障AI服务高可用

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 企业级应用如何利用Taotoken的容灾与路由能力保障AI服务高可用 对于将大模型能力深度集成到关键业务流程的企业应用而言&#xff0…...

技术赋能:BilibiliDown如何用智能解析引擎重塑视频下载工作流

技术赋能&#xff1a;BilibiliDown如何用智能解析引擎重塑视频下载工作流 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.com/gh_mi…...