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

单例模式的写法

单例模式(Singleton Pattern)是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点。常用于管理共享资源(如数据库连接、配置文件、线程池等)。在实际编码中,有多种实现单例模式的方法,下面我会展示几种常见的写法。

1. 懒汉式(Lazy Initialization)

懒汉式单例模式只有在第一次使用实例时才会创建实例。懒汉式通常是延迟加载,但可能会存在线程安全问题,需要注意。

普通懒汉式(线程不安全)
public class Singleton { private static Singleton instance; // 私有构造函数,防止外部实例化 private Singleton() {} // 获取实例的方法 public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }

这个写法在单线程环境下是有效的,但在多线程环境下,如果多个线程同时进入 if (instance == null) 判断,可能会创建多个实例。因此需要考虑线程安全问题。

线程安全的懒汉式
 
public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }

通过 synchronized 关键字确保线程安全,但同步锁会带来性能开销,影响效率。

双重检查锁(推荐)
 
public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }

这种方式称为双重检查锁定(Double-Checked Locking)。volatile 关键字确保变量的可见性,避免出现指令重排序的问题。

2. 饿汉式(Eager Initialization)

饿汉式单例模式在类加载时就创建实例,线程安全且不需要同步,但不能延迟实例化。

 
public class Singleton { // 类加载时即初始化实例 private static final Singleton instance = new Singleton(); private Singleton() {} public static Singleton getInstance() { return instance; } }

优点是线程安全,并且实现简单。缺点是如果实例的创建过程比较重或者类加载时不一定会用到实例,就会造成浪费。

3. 静态内部类(推荐)

静态内部类方式是推荐的单例模式实现方式,它结合了饿汉式的优点和懒汉式的延迟加载特性。类加载时不会立即创建实例,只有在 getInstance() 被调用时才会加载静态内部类并创建实例。此方法实现线程安全,且没有同步带来的性能问题。

 
public class Singleton {private Singleton() {
} private static class SingletonHelper 
{ // 静态内部类仅在第一次使用时加载 private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHelper.INSTANCE; } }

静态内部类的加载是由 JVM 保证的,即线程安全,并且延迟加载。

4. 枚举式(Effective Java 推荐)

枚举实现单例模式是最简单和最安全的方式,能够防止反序列化、反射攻击等问题。它由 JVM 保证线程安全和单例性。

public enum Singleton { INSTANCE; public void someMethod() { // 实现某些方法 } }

枚举类型在 Java 中是唯一的实例,JVM 会自动处理枚举的创建、序列化和反射问题,因此这种方式既简单又安全。

总结

  • 懒汉式:延迟加载,线程安全性差(需要双重检查锁定)。
  • 饿汉式:类加载时立即创建实例,线程安全,但浪费资源(如果实例不常用)。
  • 静态内部类:延迟加载,线程安全,不存在性能问题,推荐使用。
  • 枚举式:最安全、最简洁,JVM 保证唯一性,适合用于单例模式。

通常推荐使用 静态内部类枚举式,它们具有较高的性能并能避免常见的错误。

相关文章:

单例模式的写法

单例模式(Singleton Pattern)是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点。常用于管理共享资源(如数据库连接、配置文件、线程池等)。在实际编码中,有多种实现单例模式的方法&…...

Selenium实践总结

1.使用显示等待而不是隐式等待 隐式等待可能会导致不可预测的测试行为,尤其是在动态 Web 应用程序中。显式等待,它允许您 等待特定条件发生后再继续测试,这种方法提供了更多的控制和可靠性。 WebDriverWait wait new WebDriverWait(drive…...

Python数据可视化小项目

英雄联盟S14世界赛选手数据可视化 由于本学期有一门数据可视化课程,课程结课作业要求完成一个数据可视化的小Demo,于是便有了这个小项目,课程老师要求比较简单,只要求熟练运用可视化工具展示数据,并不要求数据来源&am…...

Python毕业设计选题:基于python的白酒数据推荐系统_django+hive

开发语言:Python框架:djangoPython版本:python3.7.7数据库:mysql 5.7数据库工具:Navicat11开发软件:PyCharm 系统展示 管理员登录 管理员功能界面 用户管理 白酒管理 系统管理 看板展示 系统首页 白酒详情…...

SQL-leetcode-180. 连续出现的数字

180. 连续出现的数字 表:Logs -------------------- | Column Name | Type | -------------------- | id | int | | num | varchar | -------------------- 在 SQL 中,id 是该表的主键。 id 是一个自增列。 找出所有至少连续出现三次的数字。 返回的…...

Unity中如何修改Sprite的渲染网格

首先打开SpriteEditor 选择Custom OutLine,点击Genrate 则在图片边缘会出现边缘线,调整白色小方块可以调整边缘 调整后,Sprite就会按照调整后的网格渲染了。 如何在UI中使用? 只要在UI的Image组件中选择Use Sprite Mesh 即可 结果&#xff1…...

跟着 8.6k Star 的开源数据库,搞 RAG!

过去 9 年里,HelloGitHub 月刊累计收录了 3000 多个开源项目。然而,随着项目数量的增加,不少用户反馈:“搜索功能不好用,找不到想要的项目!” 这让我意识到,仅仅收录项目是不够的,还…...

每日一题 345. 反转字符串中的元音字母

345. 反转字符串中的元音字母 简单 class Solution { public:string reverseVowels(string s) {int l 0;int r s.size() - 1;unordered_set<char> st {a,A,E,e,i,I,O,o,U,u};while(l < r){while(l<r && !st.count(s[l]) ){l;}while(l<r &&…...

Stream API 的设计融合了多个经典设计模式

Stream API 的设计融合了多个经典设计模式&#xff1a; 1. 策略模式&#xff08;Strategy Pattern&#xff09; 策略模式定义了一个算法的家族&#xff0c;将每个算法封装起来&#xff0c;并使它们可以互换。Stream API 中的每个操作&#xff08;如 filter(), map()&#xff…...

jmeter混合场景测试,设置多业务并发比例(吞吐量控制器)

jmeter混合场景测试&#xff0c;设置多业务并发比例&#xff08;吞吐量控制器&#xff09; 测试目的 为了验证需求提出的性能要求&#xff0c;结合实际可能的高压力场景&#xff0c;较全面的检测系统的性能表现。 测试方法 根据需求调研的业务模型和交易占比&#xff0c;设置不…...

直流有刷电机多环控制(PID闭环死区和积分分离)

直流有刷电机多环控制 提高部分-第8讲 直流有刷电机多环控制实现(1)_哔哩哔哩_bilibili PID模型 外环的输出作为内环的输入,外环是最主要控制的效果,主要控制电机的位置。改变位置可以改变速度,改变速度是受电流控制。 实验环境 【 !】功能简介: 按下KEY1使能电机,按下…...

vue-axios+springboot实现文件流下载

前端vue代码&#xff1a; <template><div class"app-container documentation-container"><div><el-button type"primary" click"downloadFile(test.xlsx)">下载test.xlsx</el-button></div></div> …...

selenium执行js

JS知识 获取元素 document.getElement 移除属性&#xff1a;removeAttribute("xx") 窗口移动&#xff1a;window.scrollTo(0, document.body.scrollHeight)方法 drivier.execute_script(js)场景&#xff1a; 日期选择框&#xff0c;不能输入&#xff0c;只能设置…...

每日算法Day11【左叶子之和、找树左下角的值、路径总和】

404.左叶子之和 算法链接: 404. 左叶子之和 - 力扣&#xff08;LeetCode&#xff09; 类型: 二叉树 难度: 简单 思路&#xff1a;要判断一个节点是否为左叶子节点&#xff0c;只能通过其父节点进行判断。 题解: /*** Definition for a binary tree node.* public class Tr…...

分享一下使用 AI 开发个人工具的迭代过程

分享一下使用 AI 开发个人工具的迭代过程&#xff1a;1. 找 gpt/claude 要一个 super shady coder 的人设 prompt&#xff1b;2. 简单介绍项目背景和基础需求给 gemini&#xff0c;生成最初的细化需求&#xff1b;3. 根据细化需求再次分析&#xff0c;完善边界条件&#xff0c;…...

大型语言模型(LLMs)演化树 Large Language Models

大型语言模型&#xff08;LLMs&#xff09;演化树 Large Language Models flyfish 下面的图来自论文地址 Transformer 模型&#xff08;如 BERT 和 GPT-3&#xff09;已经给自然语言处理&#xff08;NLP&#xff09;领域带来了革命性的变化。这得益于它们具备并行化能力&…...

部分背包问题

本节学习解决部分背包问题,部分背包代表物品可以按照一定比例被分割,而后放入背包内.这是十分经典的用贪心算法解决的问题. 问题描述: 给定一些物品,用matrix表示各个物品的属性,第一项表示物品的质量,第二项表示物品的总价值.现有一背包最大承重为M,试求如何让背包中所装物品…...

教师管理系统

大概功能&#xff1a; 1.显示所有教师 2.按姓名查找教师 3.按工号查找教师 4.增加教师 5.删除教师 6.退出 数据会保存到 txt 文件里面 姓名&#xff1a;必须是中文 手机号码&#xff1a;必须是11位&#xff0c;必须是数字 效果展示&#xff1a; 代码展示&#xff1a; Teache…...

Word论文交叉引用一键上标

Word论文交叉引用一键上标 1.进入Microsoft word使用CtrlH快捷键或单击替换按钮 2.在查找内容中输入[^#] 3.鼠标点击&#xff0c;标签为“替换为&#xff1a;”的文本框&#xff0c;注意光标一定要打在图红色方框圈中的文本框中&#xff01; 4.点击格式选择字体 5.勾选上标…...

集成方案 | Docusign + 蓝凌 EKP,打造一站式合同管理平台,实现无缝协作!

本文将详细介绍 Docusign 与蓝凌 EKP 的集成步骤及其效果&#xff0c;并通过实际应用场景来展示 Docusign 的强大集成能力&#xff0c;以证明 Docusign 集成功能的高效性和实用性。 在当今数字化办公环境中&#xff0c;企业对于提高工作效率和提升用户体验的需求日益迫切。蓝凌…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域&#xff0c;无损检测&#xff08;NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统&#xff0c;以非接触式光学麦克风技术为核心&#xff0c;打破传统检测瓶颈&#xff0c;为半导体、航空航天、汽车制造等行业提供了高灵敏…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...