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

Java中实现单例模式的方式

1. 使用静态内部类实现单例模式

在Java中,使用静态内部类实现单例模式是一种常见而又有效的方式。这种方式被称为“静态内部类单例模式”或者“Holder模式”。这种实现方式有以下优点:

  • 懒加载(Lazy Initialization):静态内部类不会在外部类加载的时候就被加载,而是在第一次被调用的时候才会加载。这就实现了懒加载,即在需要的时候才创建单例对象,避免了在应用启动时就创建对象的开销。

  • 线程安全(Thread-Safe):由于静态内部类只会被加载一次,因此在加载过程中,其他线程无法访问静态内部类的加载过程。这就天然地保证了线程安全性。

public class Singleton {// 私有化构造函数,防止外部直接实例化private Singleton() {}// 静态内部类,用于持有单例对象private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}// 获取单例对象的方法public static Singleton getInstance() {return SingletonHolder.INSTANCE;}
}

2. 使用序列化和反序列化实现单例模式

在Java中,使用标准的序列化和反序列化机制时,可能会破坏单例模式,因为反序列化会创建一个新的对象。为了避免这个问题,可以在单例类中添加一个特殊的方法,以便在反序列化时返回现有的单例对象。

import java.io.*;public class Singleton implements Serializable {private static final long serialVersionUID = 1L;// 私有化构造函数,防止外部直接实例化private Singleton() {}// 单例实例private static final Singleton INSTANCE = new Singleton();// 获取单例对象的方法public static Singleton getInstance() {return INSTANCE;}// 在反序列化时,确保返回相同的单例对象protected Object readResolve() throws ObjectStreamException {return INSTANCE;}public static void main(String[] args) {// 序列化try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singleton.ser"))) {oos.writeObject(Singleton.getInstance());} catch (IOException e) {e.printStackTrace();}// 反序列化try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("singleton.ser"))) {Singleton deserializedInstance = (Singleton) ois.readObject();System.out.println("Original Singleton HashCode: " + Singleton.getInstance().hashCode());System.out.println("Deserialized Singleton HashCode: " + deserializedInstance.hashCode());} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}
}

readResolve() 是一个特殊的回调方法,用于在反序列化时返回实际要返回的对象。这个方法允许开发者指定在反序列化过程中应该返回哪个对象。

3. 使用静态代码块实现单例模式

使用静态代码块实现单例模式是一种常见的方式。通过在静态代码块中进行对象的实例化,可以保证在类加载的时候只执行一次,从而实现单例模式。

public class Singleton {// 私有化构造函数,防止外部直接实例化private Singleton() {}// 单例实例private static final Singleton INSTANCE;// 静态代码块,在类加载时执行,用于初始化单例实例static {try {INSTANCE = new Singleton();} catch (Exception e) {throw new RuntimeException("Error creating singleton instance");}}// 获取单例对象的方法public static Singleton getInstance() {return INSTANCE;}public static void main(String[] args) {// 获取单例对象Singleton singleton = Singleton.getInstance();}
}

4. 使用枚举实现单例模式

在Java中,使用枚举(enum)实现单例模式是一种简洁且线程安全的方式。枚举本身就天然地具有单例的特性,保证在任何情况下都只有一个实例。这是因为Java中的枚举类型是线程安全且只能被实例化一次的。

  1. JVM保证枚举的线程安全性: Java中的枚举类型在JVM层面被设计为线程安全的,这是因为枚举实例在类加载的时候就被创建,且JVM会保证每个枚举值只被实例化一次。
  2. 保证实例的唯一性: 枚举类型的实例是在枚举类加载时被创建的,而且在整个应用程序的生命周期中,它们只会被创建一次。这就保证了枚举实例的唯一性,因此枚举天生就符合单例模式的要求。
  3. 简洁且防御反射攻击: 使用枚举实现单例模式的代码非常简洁,而且防御了一些反射攻击,因为枚举的实例在类加载的时候就被创建,不会受到反射的影响。
public enum Singleton {INSTANCE; // 单例实例// 可以在枚举中添加其他方法public void someMethod() {// 实现方法逻辑}public static void main(String[] args) {// 获取单例对象Singleton singleton = Singleton.INSTANCE;// 调用其他方法singleton.someMethod();}
}

相关文章:

Java中实现单例模式的方式

1. 使用静态内部类实现单例模式 在Java中,使用静态内部类实现单例模式是一种常见而又有效的方式。这种方式被称为“静态内部类单例模式”或者“Holder模式”。这种实现方式有以下优点: 懒加载(Lazy Initialization):静…...

Vue3-01-创建项目

环境准备 1.需要用到 16.0 以及更高版本的 node.js 2.使用vscode编辑器进行项目开发可以在命令行中查看node的版本号: node -v创建项目 1.准备一个目录 例如,我创建项目的时候是在该目录下进行的;D:\projectsTest\vue3project2.执行创建命令(*&#x…...

Go 语言中的反射机制

欢迎大家到我的博客浏览&#xff0c;更好的阅读体验请点击 反射 | YinKais Blog 反射在大多数的应用和服务中并不常见&#xff0c;但是很多框架都依赖 Go 语言的反射机制简化代码。<!--more-->因为 Go 语言的语法元素很少、设计简单&#xff0c;所以它没有特别强的表达能…...

[leetcode 前缀和]

525. 连续数组 M :::details 给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组&#xff0c;并返回该子数组的长度。 示例 1: 输入: nums [0,1] 输出: 2 说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。示例 2: 输入: nums [0,1,0] 输出: …...

Python与ArcGIS系列(十五)根据距离抓取字段

目录 0 简述1 实例需求2 arcpy开发脚本0 简述 在处理gis数据的时候,会遇到这种需求:将一个图层与另一个图层中相近的要素进行字段赋值。本篇将介绍如何利用arcpy及arcgis的工具箱实现这个功能。 1 实例需求 为了介绍这个功能的实现,我们需要有一个特定的功能需求。在这里选…...

YOLOv8分割训练及分割半自动标注

YOLOv8是基于目标检测算法YOLOv5的改进版,它在YOLOv5的基础上进行了优化和改进,加入了一些新的特性和技术,如切片注意力机制、骨干网络的选择等。 本文以yolov8-seg为基准,主要整理分割训练流程及使用v8分割模型进行半自动标注的过程。 一、v8-seg训练 1.1 环境配置 github…...

jsp页面通过class或者id获取a标签上的属性的值

要通过class和id两种方式获取a标签上的某个属性的值&#xff0c;或者给其赋值&#xff0c;可以使用JavaScript。以下是两种方法的示例&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name&q…...

题目:美丽的区间(蓝桥OJ 1372)

题目描述&#xff1a; 解题思路&#xff1a; 采用双指针的快慢指针。 图解 可以采用前缀和&#xff0c;但会相较麻烦。 题解&#xff1a; #include<bits/stdc.h> using namespace std;const int N 1e5 9; int a[N];// 因为是连续区间&#xff08;连续区间&#xff1…...

解决:During handling of the above exception, another exception occurred

解决&#xff1a;During handling of the above exception, another exception occurred 文章目录 解决&#xff1a;During handling of the above exception, another exception occurred背景报错问题报错翻译报错位置代码报错原因解决方法参考内容&#xff1a;今天的分享就到…...

计算机基础知识65

cookie和session的使用 # 概念&#xff1a;cookie 是客户端浏览器上的键值对 # 目的&#xff1a;为了做会话保持 # 来源&#xff1a;服务端写入的&#xff0c;服务端再返回的响应头中写入&#xff0c;浏览器会自动取出来 存起来是以key value 形式&#xff0c;有过期时间、path…...

Python开发运维:Python垃圾回收机制

目录 一、理论 1.Python垃圾回收机制 一、理论 1.Python垃圾回收机制 &#xff08;1&#xff09;引⽤计数器 1&#xff09;环状双向链表 refchain 在python程序中创建的任何对象都会放在refchain链表中。 name "david" age 20 hobby ["篮球",游泳…...

ros2/ros安装ros-dep||rosdep init错误

第一个错误的做法&#xff1a; sudo apt-get install python3-pip sudo pip3 install 6-rosdep sudo 6-rosdep 如果使用上述代码将会摧毁整个系统&#xff0c;不重装系统反正我是搞不定啊&#xff0c;因为我不知道那个写软件的人到底做了什么。因为这个我安装的版本是humble&…...

《深入理解计算机系统》学习笔记 - 第四课 - 机器级别的程序

Lecture 05 Machine Level Programming I Basics 机器级别的程序 文章目录 Lecture 05 Machine Level Programming I Basics 机器级别的程序intel 处理器的历史和体系结构芯片的构成AMD 公司(Advanced Micro Devices&#xff0c;先进的微型设备) C, 汇编, 机器代码定义汇编/机器…...

云原生(Cloud Native)——概念,技术,背景,优缺点,实践例子

云原生&#xff08;Cloud Native&#xff09;是一种构建和运行应用程序的方法&#xff0c;这些应用程序充分利用云计算的优势。云原生应用程序通常设计为在现代、动态的环境中运行&#xff0c;如公共云、私有云和混合云。这种方法强调微服务架构、容器化、自动化、易于管理和可…...

ElasticSearch之线程池

ElasticSearch节点可用的CPU核的数量&#xff0c;通常可以交给ElasticSearch来自行检测和判定&#xff0c;另外可以在elasticsearch.yml中显式指定。样例如下&#xff1a; node.processors: 2如下表格中的processors即CPU核的数量。 线程池的列表 线程池名称类型线程数量队列…...

StoneDB-8.0-V2.2.0 企业版正式发布!性能优化,稳定性提升,持续公测中!

​ 11月&#xff0c;StoneDB 新版本如期而至&#xff0c;这一个月来我们的研发同学加班加点&#xff0c;持续迭代&#xff1a;在 2.2.0 版本中&#xff0c;我们针对用户提出的需求和做出了重量级更新&#xff0c;修复了一些已知和用户反馈的 Bug&#xff0c;同时对部分代码进行…...

【数据结构 — 排序 — 插入排序】

数据结构 — 排序 — 插入排序 一.排序1.1.排序的概念及其运用1.1.1排序的概念1.1.2排序运用1.1.3 常见的排序算法 二.插入排序2.1.直接插入排序2.1.1.算法讲解2.1.2.代码实现2.1.2.1.函数定义2.1.2.2.算法接口实现2.1.2.3.测试代码实现2.1.2.4.测试展示 2.2.希尔排序2.2.1.算法…...

物联网后端个人第十四周总结

物联网方面进度 1.登陆超时是因为后端运行的端口和前端监听的接口不一样&#xff0c;所以后端也没有报错&#xff0c;将二者修改一致即可 2.登录之后会进行平台的初始化&#xff0c;但是初始化的时候会卡住,此时只需要将路径的IP端口后边的内容去掉即可 3.阅读并完成了jetlinks…...

在uniapp中,可以使用那些预定义的样式类

u-flex&#xff1a;设置元素为弹性布局。u-flex-v&#xff1a;设置元素为纵向弹性布局。u-flex-h&#xff1a;设置元素为横向弹性布局。u-p-10&#xff1a;设置元素的上下左右边距为10rpx。u-p-t-10&#xff1a;设置元素的上边距为10rpx。u-p-b-10&#xff1a;设置元素的下边距…...

mybatis的数据库连接池

直接看原文 原文链接:【MyBatis】 连接池技术_mybatis自带连接池-CSDN博客 本文先不说springBoot整合mybatis后的 本文讲的是没有被springBoot整合前的mybatis自己的默认的连接池 --------------------------------------------------------------------------------------…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

Ubuntu系统多网卡多相机IP设置方法

目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机&#xff0c;交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息&#xff0c;系统版本&#xff1a;Ubuntu22.04.5 LTS&#xff1b;内核版本…...