Java单例模式源码剖析及使用场景

Java中常用的单例模式实现方式主要有以下几种:

  1. 饿汉式

这种方式在类加载时就完成了实例的创建,是线程安全的。

public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}
}

优点是简单,没有加锁开销。缺点是如果从始至终都没有使用到该实例,就会造成内存的浪费。

  1. 懒汉式(线程不安全)

这种方式只有在第一次调用实例时才会创建实例对象,节省资源。但是线程不安全。

public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
  1. 懒汉式(线程安全,同步方法)

为了解决上述线程不安全问题,可以将getInstance()方法加同步锁。但是会造成不必要的同步开销。

public class Singleton {private static Singleton instance;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
  1. 懒汉式(线程安全,同步代码块)

这种方式相比于同步方法,可以减少不必要的同步开销。

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

这种方式是单例模式的经典实现方式,兼顾了线程安全性和性能。

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;}
}
  1. 静态内部类

这种方式利用了类加载机制来保证线程安全,也是一种比较好的实现方式。

public class Singleton {private Singleton() {}private static class SingletonHolder {private static final Singleton instance = new Singleton();}public static Singleton getInstance() {return SingletonHolder.instance;}
}
  1. 枚举单例

这种方式是最简单的单例模式实现,由JVM从根本上确保了线程安全和单例。

public enum Singleton {INSTANCE;public void doSomething() {// ...}
}

每种实现方式各有优缺点:

  • 饿汉式简单,但可能造成内存浪费。
  • 懒汉式节省资源,但需要处理线程安全问题。
  • 双重检查锁定是较优的一种实现。
  • 静态内部类利用了类加载机制,是一种比较好的实现方式。
  • 枚举单例最简单,由JVM保证线程安全和单例。

在实际开发中,可根据应用场景选择合适的单例实现方式。如果对单例对象的使用率较高,可以选择饿汉式或静态内部类的实现方式;如果对单例对象的使用率不太高,可以选择懒汉式或双重检查锁定的实现方式;如果项目中习惯使用枚举类,也可以采用枚举单例的实现方式。

Java单例模式是一种常用的设计模式,它的目的是确保一个类只有一个实例,并提供一个全局访问点,用于访问该实例。单例模式可以确保一个类只有一个实例对象,从而避免对资源的多重占用。

1. 通俗理解

单例模式的核心思想是控制实例的创建,确保单例类只有一个实例对象。我们可以把它比作一个公司只有一个老板,不管从哪个门进去,看到的都是同一个老板。这样的好处是可以节省资源,避免对象的重复创建和销毁。

2. 项目案例

在项目开发中,单例模式被广泛应用。例如,我们常常需要维护一个配置文件对象,用于存储系统的配置信息。由于配置数据对于整个系统来说是相同的,因此我们只需要创建一个实例即可。

public class ConfigManager {private static ConfigManager instance;private Map<String, String> configs;private ConfigManager() {configs = loadConfigsFromFile();}public static ConfigManager getInstance() {if (instance == null) {synchronized (ConfigManager.class) {if (instance == null) {instance = new ConfigManager();}}}return instance;}public String getConfig(String key) {return configs.get(key);}private Map<String, String> loadConfigsFromFile() {// 从文件加载配置信息}
}

在上面的例子中,ConfigManager类通过私有构造函数和静态的getInstance()方法实现了单例模式。我们可以在任何需要访问配置信息的地方使用ConfigManager.getInstance()获取单例对象。

3. Java源码案例

在java.lang标准库中,也存在一些单例模式的实现。比如,Runtime类就是一个典型的单例类,用于获取与当前Java应用程序相关的运行时对象。

public class Runtime {private static Runtime currentRuntime = new Runtime();public static Runtime getRuntime() {return currentRuntime;}private Runtime() {}// 其他方法...
}

在Runtime类的实现中,通过一个私有静态变量currentRuntime持有单例实例,getRuntime()方法返回这个实例。私有构造函数确保了外部无法直接创建Runtime对象。

总的来说,单例模式可以通过私有化构造函数、提供静态方法获取实例等方式实现。它确保了应用程序中一个类只有一个实例,从而节省资源,并提供了一个全局访问点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/726741.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mac vs code 文件滑到底很多空白的解决办法

ref&#xff1a;https://stackoverflow.com/questions/1747282/how-to-make-visual-studio-editor-stop-scrolling-past-bottom-of-a-file/40588828#40588828 设置、user settings: 加入&#xff1a;"editor.scrollBeyondLastLine": false

Windows系统下使用SVN版本管理的指南

前言 版本控制对于软件开发来说至关重要&#xff0c;它不仅帮助我们管理源代码的历史记录&#xff0c;也使得多人协作变得可能。SVN&#xff08;Subversion&#xff09;是一个流行的版本控制系统&#xff0c;特别是在Windows环境中&#xff0c;通过使用如TortoiseSVN这样的客户…

oracle linux7.9(centos7.9)安装nvidia GPU显卡驱动

一.业务场景 公司服务器配置了nvidia GPU显卡&#xff0c;安装的是oracle linux7.9操作系统&#xff0c;以下是安装GPU显卡驱动的操作。 二.GPU显卡驱动的前安装步骤 1.安装前的依赖软件的安装 yum -y install epel-release kernel-devel dkms gcc备注&#xff1a;利用unam…

自己优化重写了一个定时批量自动预约茅台的系统,每天帮我全家自动预约

自己优化重写了一个定时批量自动预约茅台的系统&#xff0c;每天帮我全家自动预约&#xff0c;预约结果通过邮件推送给我&#xff0c;每天手机能收到预约结果 这里写一下思路&#xff1a; 我并不是自己重头写了这个软件&#xff0c;只是基于开源系统优化了这个软件个人使用&am…

四信全球化拓展再启新篇!LoRa传感器与云平台领航智能感知时代

随着科技浪潮的不断推进&#xff0c;物联网已逐渐融入我们的生活。刚刚结束的MWC24盛会上&#xff0c;四信带来了一系列前沿技术成果&#xff0c;不仅将5G技术成功扩展至当前市场主流类型的终端&#xff0c;更携手联通、ASR等业界巨头&#xff0c;在连接、5G RedCap、AI、LoRa以…

SpringBoot整合【RocketMQ】

目录 1.POM文件添加依赖及yml配置 2.RocketmqUtil 3.生产者&#xff08;异步发送示例&#xff09; 4.消费者 5.测试 1.POM文件添加依赖及yml配置 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter&l…

【安装教程】安装tensorflow-gpu版本

【安装教程】安装tensorflow-gpu版本 NOTE:准备工作TensorFlow安装1、 确定TensorFlow版本2、使用pip直接安装3、输入安装指令 TensorFlow安装后测试 NOTE: 如果不是首次安装tensorflow&#xff0c;卸载TensorFlow相关的内容&#xff0c;包括依赖的包&#xff08;tensorflow-e…

Base64转为图片

/*** base64转为图片* 文件路径:到文件夹即可,代码里会在文件夹里生成对应的jpg文件*/ public static String base64ToJpg(String path,String base64){String imageCode =""; if (!imageCode.equals("data:image/jpg;base64,")) {imageCode = &quo…

PokéLLMon 源码解析(六)

.\PokeLLMon\poke_env\teambuilder\teambuilder_pokemon.py """This module defines the TeambuilderPokemon class, which is used as an intermediate format to specify pokemon builds in teambuilders custom classes. """ # 导入必要的模…

存储过程:深入理解MySQL存储过程及其优势

目录 1. 创建存储过程 2. 带参数的存储过程 3. 返回值的存储过程 4. 错误处理 5. 存储过程的优势 在MySQL中&#xff0c;存储过程&#xff08;Stored Procedure&#xff09;是一组为了完成特定功能的SQL语句集合&#xff0c;这些语句被编译后存储在数据库服务器中&#xf…

光线追踪10 - Dielectrics( 电介质 )

水、玻璃和钻石等透明物质都属于电介质。当光线射入这些物质时&#xff0c;会分为反射光线和折射&#xff08;透射&#xff09;光线。我们将通过随机选择反射或折射来处理这一现象&#xff0c;每次相互作用只生成一条散射光线。11.1 Refraction 最难调试的部分是折射光线。通常…

铅酸废电池回收螯合树脂CH-90除镉系统

项目名称 某再生资源公司铅酸废电池回收除镉项目 工艺选择 化学沉淀系统过滤系统螯合树脂深度除镉系统 工艺原理 镉离子沉淀后进入螯合树脂除镉树脂 项目背景 铅酸蓄电池作为广泛应用的化学电源&#xff0c;凭借其电压稳定性、优异的功率性能&#xff0c;以及高性价比等…

大数据开发(Java面试真题-卷一)

大数据开发&#xff08;Java面试真题&#xff09; 1、讲一下 JVM 的垃圾回收的相关概念&#xff1f;2、JVM 常见调优方法有哪些&#xff1f;3、请解释下Java中的线程池是什么&#xff0c;如何使用线程池来提高程序的性能&#xff1f;4、请解释Java中HashMap和HashTable的区别&a…

LVS集群(Linux Virtual server)

集群概念lvs模型lvs调度算法lvs实现lvs高可用性&#xff0c;负载均衡 1 集群和分布式 系统性能扩展方式&#xff1a; Scale UP&#xff1a;垂直扩展&#xff0c;向上扩展,增强&#xff0c;性能更强的计算机运行同样的服务 升级单机的硬件设备Scale Out&#xff1a;水平扩展…

Linux Ubuntu系统安装MySQL并实现公网连接本地数据库【内网穿透】

文章目录 前言1 .安装Docker2. 使用Docker拉取MySQL镜像3. 创建并启动MySQL容器4. 本地连接测试4.1 安装MySQL图形化界面工具4.2 使用MySQL Workbench连接测试 5. 公网远程访问本地MySQL5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定TCP地址远程访问 前言 本文主…

el-table 插入单选并进行校验

<template><div><el-form :model"list" ref"ruleForm"><el-table :data"list.tableData" style"width: 100%"><el-table-column prop"time" label"日期" width"180"><…

STM32 学习9 中断、外部中断及定时器中断

STM32 学习9 中断、外部中断及定时器中断 一、STM32中断介绍一、STM32中断介绍1. 什么是中断&#xff1f;2. 中断在嵌入式系统中的作用和重要性3. STM32中断的概述 4. 中断的优先级4.1 中断优先级级别4.2 中断优先级分类&#xff08;1&#xff09;硬件优先级&#xff08;2&…

挑战杯 基于深度学习的目标检测算法

文章目录 1 简介2 目标检测概念3 目标分类、定位、检测示例4 传统目标检测5 两类目标检测算法5.1 相关研究5.1.1 选择性搜索5.1.2 OverFeat 5.2 基于区域提名的方法5.2.1 R-CNN5.2.2 SPP-net5.2.3 Fast R-CNN 5.3 端到端的方法YOLOSSD 6 人体检测结果7 最后 1 简介 &#x1f5…

Nuxt2升级Nuxt3指南(二):nuxt.config.js配置文件

一、代码移植原则 前置说明&#xff1a;根据项目开发的实际情况&#xff0c;本次升级不采用Typescript。 升级的原则是开始尽量的简单配置&#xff0c;将代码分阶段逐步移植到新版本框架上&#xff0c;遇到问题逐一排查解决。 大致阶段&#xff0c;可以分为&#xff1a; 第一…

在idea中如何开启项目的热部署

热部署&#xff1a;就是当我们IDEA的项目在运行期间&#xff0c;我们修改代码以后&#xff0c;不需要我们自己重启项目&#xff0c;IDEA就会自动的重启项目 在idea中开启项目热部署的步骤 第一步&#xff1a;引入热部署的依赖 <dependency><groupId>org.springfr…