深入理解java设计模式之单例模式
目录
- 概述
- 单例模式是什么
- 单例模式的使用场景
- 单例模式的优缺点
- 单例模式的几种实现方式
- 饿汉式
- 懒汉式
- 双重检查锁定机制
- 静态内部类
- 枚举
- 使用容器
- 几种可能破坏单例类的方法
- 多线程环境下的竞争条件
- 使用反射机制
- 使用序列化
- 多个类加载器
概述
单例模式是什么
定义:单例模式确保一个类在应用程序中只有一个对象实例存在,并提供一种全局访问该实例的方式。
单例模式的使用场景
这种模式适用于需要共享资源或需要集中管理某些状态或配置的场景。通过使用单例模式,可以确保全局只有一个实例,避免了多个实例导致的资源浪费或状态不一致的问题。
同时,其他部分的代码只能通过单例类提供的公共访问点来获取该实例,从而限制了对实例的直接访问。
单例模式的优缺点
优点:
- 确保只有一个实例:单例模式确保在整个应用程序中只有一个实例存在,这对于某些资源的共享和状态的集中管理非常有用。
- 全局访问点:通过单例模式,可以提供一个公共访问点,让其他部分的代码可以方便地访问该实例。
- 节省资源:由于只有一个实例存在,可以避免重复创建对象,从而节省了系统资源的使用。
- 状态一致性:单例模式可以确保实例的状态始终保持一致,避免了多个实例之间的状态冲突。
缺点:
- 难以扩展:由于单例模式只允许存在一个实例,因此在需要扩展功能时可能会遇到困难。如果需要更多的实例或者多态的行为,单例模式可能不是最佳选择。
- 全局状态:由于单例模式的实例是全局可访问的,可能会导致全局状态的增加,增加了代码的复杂性和维护难度。
- 对象生命周期管理:单例模式的实例在整个应用程序的生命周期中存在,可能会导致对象的生命周期变得复杂,增加了对对象生命周期管理的要求。
单例模式的几种实现方式
饿汉式
饿汉式顾名思义,饥不择食,在类加载时就创建了单例对象,并在整个生命周期中保持不变。饿汉式的特点是在类加载时就创建实例,因此它是线程安全的。
public class Singleton {private static final Singleton INSTANCE = new Singleton();private Singleton() {// 私有的构造方法,防止外部实例化}public static Singleton getInstance() {return INSTANCE;}
}
在饿汉式单例模式中,INSTANCE是一个私有静态常量,它在类加载时就被实例化,并且保持为单例对象。私有的构造方法确保其他类无法直接实例化该类。
通过getInstance()方法,可以获取到该单例对象的实例。由于在类加载时就创建了实例,因此在多线程环境下也不会有线程安全问题。
饿汉式单例模式的优点是实现简单,线程安全,能够保证在任何时候都只有一个实例存在。
但它也有一些缺点,例如在应用启动时就创建实例,可能会增加启动时间;如果该单例对象的创建过程比较耗时,对应用的性能有一定影响。另外,由于实例是在类加载时创建的,无法实现按需创建实例的延迟加载。因此,饿汉式适用于实例创建耗时较少且在应用启动时就需要使用的情况。
懒汉式
懒汉式是单例模式的另一种实现方式,它延迟实例化对象,直到第一次使用时才进行创建。懒汉式的特点是在需要时才创建实例,但需要注意线程安全的处理。
public class Singleton {private static Singleton INSTANCE;private Singleton() {// 私有的构造方法,防止外部实例化}//同步方法public static synchronized Singleton getInstance() {if (INSTANCE == null) {INSTANCE = new Singleton();}return INSTANCE;}//同步代码块public static Singleton getInstance() {if (INSTANCE == null) {synchronized (Singleton.class) {INSTANCE = new Singleton();}}return INSTANCE;}
}
INSTANCE是一个私有静态变量,它在第一次调用getInstance()方法时进行实例化。通过synchronized关键字,确保在多线程环境下只有一个线程可以进行实例化操作,从而保证线程安全性。
懒汉式单例模式的优点是在需要时才创建实例,避免了在应用启动时就进行实例化的开销。然而,需要注意线程安全性的处理,以及对性能的影响。懒汉式适用于实例创建较为耗时且在应用中可能不一定会被使用到的情况。
双重检查锁定机制
懒汉式单例模式引入了同步锁的机制,可能会在多线程环境下影响性能。每次调用getInstance()方法时都需要获取锁,即使实例已经被创建。这种同步的开销在高并发场景下可能会成为性能瓶颈。
为了解决性能问题,可以使用双重检查锁定机制,避免每次调用getInstance()都进行同步操作。
public class Singleton {private static volatile Singleton INSTANCE;相关文章:
深入理解java设计模式之单例模式
目录 概述单例模式是什么单例模式的使用场景单例模式的优缺点单例模式的几种实现方式饿汉式懒汉式双重检查锁定机制静态内部类枚举使用容器几种可能破坏单例类的方法多线程环境下的竞争条件使用反射机制使用序列化多个类加载器概述 单例模式是什么 定义:单例模式确保一个类在…...
程序员自由创业周记#36:Gap Year
程序员自由创业周记#36:Gap Year 一整年 刚过去的一周,度过了我31周岁的生日,距离结束上一份工作,刚好一年。一年过得好快,犹记得刚失业那会的迷茫,第一个月的纠结,是继续打工还是自己当“老板…...
Java 类与对象 -- Java 语言的类与对象、构造器、static、final、包和 JAR
大家好,我是栗筝i,这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 006 篇文章,在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验,并希望进…...
MTK平台纯色背景抑制
MTK中有两个机制可以抑制纯色背景的亮度,分别是Main target、Histogram。 Main target的纯色背景亮度机制原理大概如下: 将图像分成64*48块,分别统计每一块的亮度Y。 但对于纯色背景时,如果仍然使用Luma来计算,容易造…...
Linux iptables使用详解
一、Linux系统下使用iptables 在Linux中,常用的防火墙工具是iptables。以下是一些基本的iptables命令,用于配置防火墙规则。 查看现有的iptables规则: sudo iptables -L 清除所有现有的规则(慎用,可能导致服务不可用…...
算法02 递归算法及其相关问题
递归 在编程中,我们把函数直接或者间接调用自身的过程叫做递归。 递归处理问题的过程是:通常把一个大型的复杂问题,转变成一个与原问题类似的,规模更小的问题来进行求解。 递归的三大要素 函数的参数。在用递归解决问题时&…...
三个pdf工具和浏览软件(pdftk,muppdf,epdfview)
安装pdftk pdftk是一款功能强大的PDF处理工具,主要用于对PDF文件进行各种操作。它提供了丰富的功能,包括但不限于合并、拆分、旋转、加密、解密、添加水印、从PDF文档中解出附件等。pdftk分为图形界面版本和命令行版本,适用于不同的用户需求…...
UKP3d的excel汇总表
长沙某正版用户就EXCEL的图框两点问题,进行交流: 1.1.图框:中英文两行,字体样式,logo加上等个性化需求; cbl回复:9.3后续版本迭代会加图框(解决用户个性化需求)…...
体验亚马逊AIGC——Amazon Bedrock
前言 随着人工智能技术的不断发展,我们已经进入了一个全新的时代,即AI驱动的时代。在这个时代,人工智能已经逐渐成为我们生活中不可或缺的一部分,它可以帮助我们更好地处理各种复杂的问题,提高我们的工作效率ÿ…...
Vue前端服务是什么:深入解析与实际应用
Vue前端服务是什么:深入解析与实际应用 在现今的互联网开发领域,前端技术日新月异,Vue.js作为其中的佼佼者,其前端服务更是成为了众多开发者关注的焦点。那么,Vue前端服务究竟是什么?它有哪些核心要素和实…...
mysql_ssl_rsa_setup使用详解
mysql_ssl_rsa_setup 是一个MySQL附带的工具,用于自动创建SSL证书和密钥文件,以便在MySQL服务器与客户端之间启用安全的SSL/TLS连接。这对于确保数据传输的安全性是非常重要的,尤其是在不安全的网络环境中。下面是对mysql_ssl_rsa_setup使用的…...
FreeSWITCH入门到精通系列(三):FreeSWITCH基础概念与架构
FreeSWITCH入门到精通系列(三):FreeSWITCH基础概念与架构 前言 在前两篇博客中,我们介绍了FreeSWITCH的基本概念和安装与配置。本篇文章将深入探讨FreeSWITCH的基础概念和架构,帮助您更好地理解这个强大的通信平台的…...
【C++】AVL树/红黑树实现及map与set的封装
前言 【C】二叉树进阶(二叉搜索树) 这篇文章讲述了关于二叉搜索树知识,但是二叉搜索树有其自身的缺陷,假如往树中插入的元素有序或者接近有序,二叉搜索树就会退化成单支树,时间复杂度会退化成O(N)ÿ…...
利用CSS隐藏HTML元素并插入替代内容
在创建一个支持切换阅读模式和答题模式的Anki问答题模板中,我创建了一个支持切换阅读模式和答题模式的问答题模板,该文最终利用JavaScript将Anki输出的向下箭头删除,并插入自定义的提示语。经过进一步测试,发现实现上述功能完全不…...
第二节 单机版本redis部署
1. 部署环境 操作系统:centos7.XCPU: 2H内存:4GIP: 192.168.100.102部署版本: redis-7.0.15.tar.gz基础环境: gcc下载 2. 上传Redis安装包 [rootlocalhost opt]# ll 总用量 2932 drwxrwxr-x. 8 root root 4096 1…...
Vim 常用指令
Vim 是一款功能强大且高度可定制的文本编辑器。其高效的编辑方式使其成为许多程序员和系统管理员的首选。 1. Vim 的基本模式 Vim 具有以下几种基本模式: 正常模式(Normal mode):用于浏览和编辑文本(按 ESC 进入&am…...
PySide6实现pdf转化为word和长图片
目录 一:实现思路 二:实现过程 三:完整代码和实现 一:实现思路 最近在使用wps,发现wps中使用pdf转化为长图片还需要收费,这么不地道。就想自己能不能用程序实现这种功能的。还好python在自动化办公领域比较强悍,对文档操作也是得心应手。因此记录下用python实现pdf转…...
嵌入式硬件VS软件,到底哪个更难?
在嵌入式系统开发中,硬件和软件是密不可分的两个方面。但是,究竟是硬件开发更具挑战性,还是软件开发更难以应对呢?本文将就这一问题展开讨论,探究嵌入式硬件和软件在开发过程中的各种挑战与特点。 一、硬件开发&#…...
Spring boot集成log4j及日志配置详解,实战,ELK使用教程。
目录 引言一、SpringBoot 集成 Log4j1. 添加 Log4j 依赖2. 移除默认的Logback组件3. 创建 Log4j 配置文件4. 配置 Log4j2 日志文件 二、Log4j2 XML 文件配置详解基本结构Appenders 配置详解Loggers 配置详解 三、日志的作用四、日志数据采集与分析1. 日志数据采集2. 日志数据分…...
element 树组件 tree 横向纵向滚动条
Html <el-cardshadow"hover"class"solo flex-2"style"height: calc(100vh - 1.6rem); border: 1px solid #ebeef5"><div slot"header" class"clearfix"><span>问题分类</span></div><div …...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
