独一无二的设计模式——单例模式(Java实现)

1. 引言

亲爱的读者们,欢迎来到我们的设计模式专题,今天的讲解的设计模式,还是单例模式哦!上次讲解的单例模式是基于Python实现(独一无二的设计模式——单例模式(python实现))的,但是目前很多实际系统是通过JAVA实现的,所以今天聊一聊基于JAVA的语言特性,单例模式的实现和应用。

2. 什么是单例模式

单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点。就像世界上只有一个太阳,我们也希望某些对象在整个应用程序中只有一个实例。单例模式适用于需要全局唯一访问的资源,如数据库连接、配置管理器、日志记录器等。

3. 单例模式的实现(Java)

基本实现

在Java中,单例模式通常使用懒汉式或饿汉式实现,以下讲解四种主要的实现方法:

懒汉式实现,懒汉式单例模式只有在第一次调用getInstance方法时才会创建实例:
public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
详细代码解析
  • instance静态变量用于存储单例实例,在类加载时,它被初始化为null
  • getInstance方法是获取实例的关键,如果instance为空,则创建一个新的实例并返回,否则返回已有的实例;
  • 私有构造函数Singleton()防止类被外部实例化,确保实例只能通过getInstance方法获取。
多线程安全的懒汉式实现,为了应对多线程环境,可以使用同步块来确保线程安全:
public class Singleton {private static Singleton instance;private static final Object lock = new Object();private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (lock) {if (instance == null) {instance = new Singleton();}}}return instance;}
}
详细代码解析
  • lock是一个同步对象,用于确保在多线程环境下,只有一个线程能够创建实例;
  • getInstance方法中使用synchronized块来加锁,确保只有一个线程能够进入创建实例的代码块。
饿汉式实现,饿汉式单例在类加载时就创建实例,相比懒汉式避免了多线程问题:
public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}
}
详细代码解析
  • instance静态变量在类加载时即被初始化,确保实例的唯一性和线程安全;
  • 私有构造函数防止外部实例化。
静态内部类实现,这种方法利用类加载机制,只有在调用getInstance时才会创建实例,确保线程安全和延迟加载:
public class Singleton {private Singleton() {}private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return SingletonHolder.INSTANCE;}
}
详细代码解析
  • SingletonHolder是一个静态内部类,包含了Singleton的唯一实例;
  • getInstance方法中返回SingletonHolder.INSTANCE,确保实例的延迟加载和线程安全。

4. 单例模式的应用场景和实例

示例一:配置文件管理

在应用程序中,配置文件通常需要全局访问且不应被重复加载。使用单例模式可以确保配置管理器只有一个实例,从而避免重复加载配置文件。

import java.util.Properties;public class ConfigurationManager {private static ConfigurationManager instance;private Properties config;private ConfigurationManager() {config = new Properties();}public static ConfigurationManager getInstance() {if (instance == null) {instance = new ConfigurationManager();}return instance;}public void setConfig(String key, String value) {config.setProperty(key, value);}public String getConfig(String key) {return config.getProperty(key);}
}

使用示例:

ConfigurationManager configManager = ConfigurationManager.getInstance();
configManager.setConfig("api_url", "https://api.example.com");
System.out.println(configManager.getConfig("api_url"));
示例二:日志记录

日志记录器是单例模式的经典应用之一,通过确保日志记录器的唯一性,我们可以统一管理日志输出,避免多个日志实例之间的混乱:

import java.util.logging.*;public class LoggerSingleton {private static LoggerSingleton instance;private Logger logger;private LoggerSingleton() {logger = Logger.getLogger("singleton_logger");ConsoleHandler handler = new ConsoleHandler();SimpleFormatter formatter = new SimpleFormatter();handler.setFormatter(formatter);logger.addHandler(handler);logger.setLevel(Level.INFO);}public static LoggerSingleton getInstance() {if (instance == null) {instance = new LoggerSingleton();}return instance;}public void log(String message) {logger.info(message);}
}

使用示例:

LoggerSingleton logger = LoggerSingleton.getInstance();
logger.log("This is a log message.");

5. 单例模式的优缺点

优点
  • 控制实例数量:确保一个类只有一个实例,节省资源;
  • 全局访问点:提供一个全局访问点,方便管理和使用。
缺点
  • 不易扩展:由于单例模式限制了实例的数量,可能不利于扩展;
  • 隐藏依赖关系:单例模式通过全局访问点使用实例,可能导致代码依赖关系不明确,不利于测试。

6. 图示

  • 单例模式的UML图:
+----------------+
|   Singleton    |
+----------------+
| - _instance    |
| - _lock        |
+----------------+
| + getInstance()|
+----------------+
  • 单例模式的示意图:

7. 总结

单例模式是一种简单而强大的设计模式,确保一个类只有一个实例,并提供全局访问点。在实际开发中,单例模式广泛应用于配置管理、日志记录等场景,通过合理地使用单例模式,我们可以有效管理和优化资源,确保系统的一致性和稳定性。

希望今天的分享能让大家对单例模式有更深入的理解,如果你在项目中也使用了单例模式,欢迎留言分享你的经验和见解!
在这里插入图片描述

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

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

相关文章

web全屏api,实现元素放大全屏,requestFullscreen,exitFullscreen

全屏api 主要方法 document.exitFullscreen(); 退出页面全屏状态,document是全局文档对象 dom.requestFullscreen(); 使dom进入全屏状态,异步,dom是一个dom元素 dom.onfullscreenchange(); 全…

专题四:Spring源码初始化环境与BeanFactory

上文我们通过new ClassPathXmlApplicationContext("applicationContext.xml");这段代码看了下Spring是如何将Xml里面内容注入到Java对象中,并通过context.getBean("jmUser");方式获得了一个对象实例,而避开使用new 来耦合。今天我们…

【TB作品】智能台灯控制器,ATMEGA128单片机,Proteus仿真

题目 8 :智能台灯控制器 基于单片机设计智能台灯控制器,要求可以调节 LED 灯的亮度,实现定时开启与关闭, 根据光照自动开启与关闭功能。 具体要求如下: (1)通过 PWM 功能调节 LED 灯亮度&#x…

娱乐圈发生震动,AI大模型技术已经取代了SNH48的小偶像?

自2023年以来,全球都被包裹在AI的惊天大潮之中,所有行业都在主动或被动地迎接改变。目前,各行业已经有大量公司正在把AI作为自身发展的最佳路径。其中,娱乐行业作为最被人们熟知的行业也在面对AI的发展时,发生着巨大变…

GMSB文章九:微生物的相关关系组间波动

欢迎大家关注全网生信学习者系列: WX公zhong号:生信学习者Xiao hong书:生信学习者知hu:生信学习者CDSN:生信学习者2 介绍 计算配对微生物在组间的相关关系波动情况进而评估不同分组的微生物状态。secom_linear 函数…

线性表与顺序存储结构(下)

前言 接上文(线性表与顺序存储结构(上))。 这些顺序存储结构的方法在顺序表上下卷中已经提到过,但是有些许不同,可以为理解顺序表提供更丰富的视角。(不过最主要的区别在于顺序表上下卷中的顺…

Python | 计算位涡平流项

写在前面 最近忙着复习、考试…都没怎么空敲代码,还得再准备一周考试。。。等考完试再慢慢更新了,今天先来浅更一个简单但是使用的python code 在做动力机制分析时,我们常常需要借助收支方程来诊断不同过程的贡献,其中最常见的一…

51单片机-点亮LED灯

目录 新建项目选择型号添加新文件到该项目设置字体和utf-8编码二极管如何区分正负极原理:CPU通过寄存器来控制硬件电路 用P2寄存器的值控制第一个灯亮进制转换编译查看P2寄存器的地址生成HEX文件把代码下载到单片机中 新建项目 选择型号 stc是中国生产的、这个里面…

利用Linked SQL Server提权

点击星标,即时接收最新推文 本文选自《内网安全攻防:红队之路》 扫描二维码五折购书 利用Linked SQL Server提权 Linked SQL server是一个SQL Server数据库中的对象,它可以连接到另一个SQL Server或非SQL Server数据源(如Oracle&a…

初学者轻松搞定19个经典的Python程序以及代码演示

Python的经典程序展示了Python语言基本特性和功能的简单示例,这些程序在学习和理解Python编程语言的过程中起着至关重要的作用. 一些常见的经典Python程序及其在学习Python时的功能: 1.Hello, World! print("Hello, World!")解释:这是Python的基本输出…

primeflex overflow样式类相关的用法和案例

文档地址&#xff1a;https://primeflex.org/overflow 案例1 <script setup> import axios from "axios"; import {ref} from "vue";const message ref("frontend variable") axios.get(http://127.0.0.1:8001/).then(function (respon…

【Flink】Flink SQL

一、Flink 架构 Flink 架构 | Apache Flink 二、设置TaskManager、Slot和Parallelism 在Apache Flink中&#xff0c;设置TaskManager、Slot和Parallelism是配置Flink集群性能和资源利用的关键步骤。以下是关于如何设置这些参数的详细指南&#xff1a; 1. TaskManager 设置 …

【漏洞复现】致远互联FE协作办公平台——SQL注入

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 致远互联FE协作办公平台是一个专注于协同管理软件领域的数智化运…

关于内存和外存文件不同字符集下占用空间大小问题

关于内存和外存不同字符集下文件占用空间大小问题 存储&#xff08;外存&#xff09;的文件中的字符&#xff1a; ASCII&#xff1a;每个字符占用1个字节&#xff0c;用来存储英文字符和常用标点符号。ISO-8859-1&#xff1a;每个字符占用1个字节&#xff0c;向下兼容ASCII。G…

DS18B20单总线数字温度传感器国产替代MY18E20 MY1820 MY18B20Z MY18B20L(一)

前言 DS18B20是全球第一个单总线数字温度传感器&#xff0c;推出时间已经超过30年&#xff0c;最早由美国达拉斯半导体公司推出&#xff0c;2001年1月&#xff0c;美信以25亿美元收购达拉斯半导体&#xff08;Dallas Semiconductor&#xff09;&#xff0c;而美信在2021年8月被…

DM达梦数据库存储过程

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

RDMA通信2:RDMA基本元素和组成 通信过程元素关系解析 视频教程

哈哈哈&#xff0c;今天我们把下面这张图理解了&#xff0c;我们的任务就完成了&#xff01; 视频教程在这&#xff1a;1.2 RDMA基本元素和组成 通信过程元素关系解析_哔哩哔哩_bilibili 一、WQ和WQE 工作队列元素(work queue element,WQE)&#xff1a;是软件下发给硬件的任务…

Apache Ranger 2.4.0 集成Hive 3.x(Kerbos)

一、解压tar包 tar zxvf ranger-2.4.0-hive-plugin.tar.gz 二、修改install.propertis POLICY_MGR_URLhttp://localhost:6080REPOSITORY_NAMEhive_repoCOMPONENT_INSTALL_DIR_NAME/BigData/run/hiveCUSTOM_USERhadoop 三、进行enable [roottv3-hadoop-01 ranger-2.4.0-hive…

什么是TOGAF架构框架的ADM方法?

ADM是架构开发方法&#xff08; Architecture Development Method&#xff09;&#xff0c;为开发企业架构所要执行的各个步骤以及它们质检的关系进行详细的定义&#xff0c;它是TOGAF规范中最为核心的内容。 ADM的具体步骤&#xff1a; 预备阶段&#xff08;Preliminary Phas…

STM32第十三课:DMA多通道采集光照烟雾

文章目录 需求一、DMA&#xff08;直接存储器存取&#xff09;二、实现流程1.时钟使能2.设置外设寄存器地址3.设置存储器地址4.设置要传输的数据量5.设置通道优先级6.设置传输方向7.使通道和ADC转换 三、数据处理四、需求实现总结 需求 通过DMA实现光照强度和烟雾浓度的多通道…