java23种常用设计模式之单例模式(Singleton)

【Java设计模式】Java设计模式之(一)单例模式(Singleton Pattern) 本文继续介绍23种设计模式详解系列之单例模式。 一、单例模式的定义 指一个类只有一个实例,且该类能自行创建这个实例的一种模式。 二、单例模式的常见例子 Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容的不一致等错误;在计算机系统中,还有 Windows 的回收站、操作系统中的文件系统、多线程中的线程池、显卡的驱动程序对象、打印机的后台处理服务、应用程序的日志对象、数据库的连接池、网站的计数器、Web 应用的配置对象、应用程序中 阅读详情

Singleton很有意思,也很容易理解,使用非常广泛。

在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样有几个好处:

1、某些类创建比较频繁,对于一些大型的对象,这可以节省一笔很大的系统开销。

2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。

3、有些像交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了,只有使用单例模式,才能保证核心交易服务器独立控制整个流程。

单例就是单一、独一无二的意思,比如每个人的DNA都是独一无二的,不可复制,每个人都是正版,除此之外还有什么不能山寨的呢?

下面是我在网上看到的一个很有意思的例子,很生动形象地说明了单例模式。

举个比较难复制的对象:皇帝

中国的历史上很少出现两个皇帝并存的时期,是有,但不多,那我们就认为皇帝是个单例模式,在这个场景中,有皇帝,有大臣,大臣是天天要上朝参见皇帝的,今天参拜的皇帝应该和昨天、前天的一样(过渡期的不考虑,别找茬哦),大臣磕完头,抬头一看,嗨,还是昨天那个皇帝,所以这个皇帝就是一个单例模式对象。

先看类图:

接着看代码,我先说的都在代码里了!

皇帝类:

package com.freedom.singleton1;
/**
 * 事先声明,本人爱扯,不喜欢看故事的请自动屏蔽//注释。
 * @author freedom
 * Emperor 皇帝类
 * 中国的历史上一般都是一个朝代一个皇帝,有两个的话,必然要PK出一个,所以亲们不要纠结PK期哦!
 */
public class Emperor {

	
	/* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */  
	private static Emperor emperor = null; //定义一个皇帝,描述一下这个皇帝的特征
	
	/* 私有构造方法,防止被实例化 */  
	private Emperor() {
		//在地球人世俗和道德条条框框下,你是不允许产生第二个皇帝,否则生灵涂炭的灾难每日都在上演
		//所以注意构造方法是private而不是public
	}

	/* 静态工程方法,创建实例 */  
	public static Emperor getInstance() {
		if (emperor == null) { // 如果皇帝还没有定义,那就定一个
			emperor = new Emperor();
		}
		return emperor;
	}

	/* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  
	public static void emperorInfo() {
		// 描述皇帝的特征:比如长得帅不帅,高不高,后宫佳丽是三千还是三万,是政治天才还是祸国殃民的蠢才……
		System.out.println("名未知,字未来,眉清目秀,身高八尺,后宫佳丽三千万,个个能歌善武,出的了厅堂,上得了战场,所以你说是政治天才还是祸国殃民的蠢才呢?");
	}
}
大臣类:

package com.freedom.singleton1;
/**
 * 事先声明,本人爱扯,不喜欢看故事的请自动屏蔽注释。
 * @author freedom
 * Minister 大臣
 * 大臣天天要上早朝拜见皇帝,今天拜的皇帝和昨天、前天的都是一样的!
 * 请忽略今天和昨天不一样的情况,因为昨天的PK肯定试一次惨不忍睹的厮杀,
 * 在历史的长河中,平均发生的概率在1/365以下。
 * 在singleton2中通用的单例模式会解决同一朝代有两个皇帝,你怎么确定你每天拜见都是同一个皇帝问题。
 */
public class Minister {

	public static void main(String[] args) {
		// 第一天
		Emperor emperor1 = Emperor.getInstance();
		emperor1.emperorInfo(); //第一天见的皇帝特征:名?字?高否?帅否?……
		// 第二天
		Emperor emperor2 = Emperor.getInstance();
		Emperor.emperorInfo(); //第二天见的皇帝特征:和昨天一样高?一样帅?……
		// 第三天
		Emperor emperor3 = Emperor.getInstance();
		emperor2.emperorInfo();//第三天见的皇帝特征:和昨天、前天一样高?一样帅?……
	}
}
大臣连续三天拜见皇帝的结果(输出皇帝的信息):


看到没,大臣天天见到的都是同一个皇帝,不会产生错乱的情况,反正都是一个皇帝,是明君是混蛋就这一个,只要提到皇帝,大家都知道指的是谁,清晰明了。

问题来了,如果同一个时期同一个朝代有两个皇帝怎么办?

上面实现的单例模式很简单,就是将构造函数的访问权限是private 的就可以了,这个模式很简单,但是简单中暗藏风险。

风险?什么风险?……

在一个B/S 项目中,每个HTTP Request 请求到J2EE的容器上后都创建了一个线程,每个线程都要创建同一个单例对象,怎么办?

好,写一个通用的单例程序,然后分析一下:

package com.freedom.singleton2;
/**
 * @author freedom
 * SingletonPattern 通用单例模式
 * 
 */
public class SingletonPattern {
	private static SingletonPattern singletonPattern = null;

	// 私有构造方法,限制不能直接new产生一个实例
	private SingletonPattern() {
	}

	public SingletonPattern getInstance() {
		if (this.singletonPattern == null) { // 如果还没有实例,则创建一个
			this.singletonPattern = new SingletonPattern();
		}
		return this.singletonPattern;
	}
}

来看看这一部分:

if (this.singletonPattern == null) { // 如果还没有实例,则创建一个
	this.singletonPattern = new SingletonPattern();
}

假设现在有两个线程A 和线程B,线程A 执行到 this.singletonPattern =new SingletonPattern(),

正在申请内存分配,可能需要0.001 微秒,就在这0.001 微秒之内,线程B 执行到if(this.singletonPattern == null),

你说这个时候这个判断条件是true 还是false?是true,那然后呢?

线程B 也往下走,于是乎就在内存中就有两个SingletonPattern 的实例了,看看是不是出问题了?

如果你这个单例是去拿一个序列号或者创建一个信号资源的时候,会怎么样?业务逻辑混乱!数据一致性校验失败!

最重要的是你从代码上还看不出什么问题,这才是最要命的!

因为这种情况基本上你是重现不了的,不寒而栗吧,那怎么修改?

有很多种方案,我就说一种,能简单粗暴地彻底解决问题的方案:

package com.freedom.singleton3;

/**
 * @author freedom 
 * SingletonPattern 通用单例模式
 */
public class SingletonPattern {

    private static final SingletonPattern singletonPattern = new SingletonPattern();

	// 限制住不能直接产生一个实例
	private SingletonPattern() {
	}

	public synchronized static SingletonPattern getInstance() {
		return singletonPattern;
	}

}

直接new 一个对象传递给类的成员变量singletonpattern,你要的时候getInstance()直接返回给你。

Excellent!

Finish!


下载源码







医学图像处理入门:如何用Python将CT灰度图转换为伪彩色图像(附代码) 本文详细介绍了如何使用Python将CT灰度图转换为伪彩色图像,提升医学图像的可读性和诊断效率。通过OpenCV和Matplotlib等工具,实现灰度值到彩色空间的映射,特别适用于突出显示特定组织密度差异。文章包含完整代码示例和临床实用技巧,适合医学影像分析初学者和Python开发者。 阅读详情

相关推荐

App渗透 - 人脸识别登录绕过

一、APP抓包和逆向破解加密算法打开APP是一个登录框抓包后发现参数被加密了使用Jadx脱源码发现,并没有加壳也没有混淆,运气很好根据经验,先搜索Encrypt、Decrypt等关键字,发现在Common.js中有一个encryptData函数定位过去,一套加解密算法都写好了放在这放到浏览器console里面调试,果然没错二、寻找注入点首先测试了一下注入明文:{"userName":"TEST'...

渗透测试研究中心 2825

23种设计模式中的单例模式(Singleton Pattern)

本篇文章将23种设计模式中的单例设计模式,此篇文章为一天学习一个设计模式系列文章,后面会分享其他模式知识。

小威的博客 2万+

VUE3如何使得大屏自适应的几种方法?

16:9。

weixin_42711805的博客 1万+

Java23种设计模式之单例模式(Singleton)

概念:单例模式在23种设计模式中属于创建型模式,是常见的设计模式之一。 案例: 这里以经典的数据库驱动连接工具类为例; 数据库连接工具类在各个业务的dao层会被初始化调用; 而每一次初始化都会在堆内存中申请一片空间,这是对堆内存资源的浪费; 如果在堆内存只开辟一片空间,各个业务的Dao层建立不同的引用进行操作,就可以资源利用最大化; ...

Jieur的博客 1152

1006. 换个格式输出整数 (15)-PAT乙级真题

1006. 换个格式输出整数 (15)让我们用字母B来表示“百”、字母S表示“十”,用“12…n”来表示个位数字n(<10),换个格式来输出任一个不超过3位的正整数。例如234应该被输出为BBSSS1234,因为它有2个“百”、3个“十”、以及个位的4。输入格式:每个测试输入包含1个测试用例,给出正整数n(<1000)。输出格式:每个测试用例的输出占一行,用规定的格式输出n。输入样例1...

柳婼 の blog 2243

C# & SQL Server 实时数据同步:7步轻松搞定,代码详解

实时数据同步是指在一个数据库中的数据发生变化时,能够立即或近乎立即地将这些变化同步到另一个数据库中。这种同步可以是单向的(从源数据库同步到目标数据库),也可以是双向的(两个数据库互相同步)。通过本文的详细讲解和代码示例,相信你已经学会了如何使用C#和SQL Server实现数据库的实时数据同步。实时数据同步不仅可以提升系统的响应速度,还能确保数据的一致性和准确性。希望这篇教程对你有所帮助,期待你在C#编程中取得更大的成就!🌟✨如果你有任何问题或建议,欢迎在评论区留言交流!

java专栏 514

23种设计模式——单例模式(Singleton)​详解

本文介绍了23种经典设计模式之——单例模式(Singleton)的说明及使用

Meteors.的博客 1104

企业AI Agent的多模态学习在用户体验优化中的应用

本文旨在为企业技术团队提供关于多模态AI Agent在用户体验优化领域的全面技术指南。多模态学习如何突破传统单模态AI的局限性企业级AI Agent的系统架构设计原则多模态特征融合的工程实现细节用户体验度量的量化方法实际部署中的性能优化策略研究范围涵盖计算机视觉、自然语言处理、语音识别等多个AI子领域的技术融合,以及它们在电商、金融、医疗等行业的应用实践。首先介绍多模态学习的核心概念和技术原理然后深入分析关键算法和数学模型接着通过完整项目案例展示实际应用。

大模型应用工坊 706

【GoF23种设计模式】02_单例模式(Singleton Pattern)

单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供一个全局访问点来获取这个实例。

weixin_48627356的博客 1314

基于DINO自监督学习对YOLO11 Backbone进行预训练

这PoolHead将获取前一层的输出并应用卷积,然后应用自适应平均池化以将特征图的空间维度减小为固定且一致的大小(1x1)。这是必需的,因为否则空间维度会根据输入的大小而变化,这将使将 DINO 头部附加到主干变得困难,因为它需要固定的输入大小。在本指南中,我们将介绍如何使用 Lightly 使用 DINO 预训练 YOLO 11主干,以及如何将其重新加载到 Ultralytics 中进行微调。您可以使用不同的大小,例如,640这与 YOLO 中的默认图像大小更一致,但它也会在训练期间消耗更多 VRAM。

如果想成为中心,那么就到中心去吧。 1014

Linux内存从0到1学习笔记(10.1 BugsShooter之cma配置过小导致页迁移繁忙而内存申请失败)

通过向武神讨教,顺便记录cma内存有空间但页繁忙(页正被访问,无法迁移)迁移不了导致cma内存分配失败的排查过程。

从0到1,突破自己 1万+

设计模式之单例模式(Singleton Pattern)

意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。主要解决:一个全局使用的类频繁地创建与销毁。何时使用:当您想控制实例数目,节省系统资源的时候。如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。关键代码:构造函数是私有的。

weixin_42294716的博客 1398

【深度学习新浪潮】Score Matching(分数匹配):原理、推导与PyTorch实战

在概率模型训练中,配分函数(归一化常数)是绕不开的难题——尤其是能量模型(EBM)、扩散模型等未归一化模型,直接计算配分函数几乎不可能。Score Matching(分数匹配)作为一种无归一化的参数估计方法,通过拟合概率密度的对数梯度(分数函数),彻底避开了配分函数的计算,成为生成建模、密度估计的核心技术之一。本文将从基础概念出发,逐步推导Score Matching的核心公式,并结合PyTorch实现一个可直接运行的实战案例,帮你彻底理解这一关键技术。Score Matching的核心是。

专注:太空算力、AI infra、异构调度、大模型成本工程 250

JAVA23种设计模式之单例模式(Singleton Pattern)

单例模式 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。 注意 单例类只能有一个实例。 单例类必须自己创建自己的唯一实例。 单例类必须给所有其他对象提供这一实例。 介绍 意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 主要解决:一个

fuu123f的博客 221

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Java 之 23 种设计模式解析——3、单例模式(Singleton)

3、单例模式(Singleton)   单例对象(Singleton)是一种常用的设计模式。在 Java 应用中,单例对象能保证在一个 JVM 中,该对象只有一个实例存在。这样的模式有几个好处: 1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。 2、省去了 new 操作符,降低了系统内存的使用频率,减轻 GC 压力。 3、有些类如交易所的核心交易引擎,控制着交易流程,...

毕富国的博客 614

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Java开发之设计模式--单例模式(Singleton)

设计模式第4篇--单例模式(Singleton)

ZaneLove's blog 1390

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

23种设计模式-单例(Singleton)设计模式

23种设计模式-单例(Singleton)设计模式

Hanson的博客 1534

java中的单例(Singleton)设计模式,详解

所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。单例模式的两种实现方式包括饿汉式与懒汉式。

共同学习,共同成长 1658

java23种设计模式之一: 单例模式(Singleton Pattern)

单例模式(Singleton Pattern)是设计模式中比较常用的一种,下面来总结单例模式的知识,包括: 1、理解什么是单例模式、单例模式有什么优点/缺点、单例模式的应用场景; 2、再来看看Java单例模式的6种代码实现方式、每种实现方式有什么需要注意的; 3、后面再来了解Java单例模式其他值得关注的地方,如比较静态方法、以及Java反...

255

GOF23设计模式之单例模式-Singleton

本文解决了哪些问题? 1. 单例的几种实现,有何异同? 2. 什么是序列化与反序列化?如何防止反序列化破坏单例? 3. 何为反射破坏单例?如何避免? 4. 如何优雅的实现单例模式? 5. 框架中如何运用单例模式的?

zhengyong14350的博客 816

【Java中23种面试常考的设计模式之单例模式(Singleton)---创建型模式】

【Java中23种面试常考的设计模式之单例模式(Singleton)---创建型模式】饿汉式、懒汉式、线程安全与线程不安全、DCL双锁检查机制(防止指令重排序)、枚举、静态内部类、实现代码

Coder_ljw的博客 401

Java23种设计模式 单例模式【Singleton Pattern】

本文章转载大佬CBF4LIFE的文章 博客地址:https://www.cnblogs.com/cbf4life/ 这个模式是很有意思,而且比较简单,但是我还是要说因为它使用的是如此的广泛,如此的有人缘, 单例就是单一、独苗的意思,那什么是独一份呢?你的思维是独一份,除此之外还有什么不能山寨的呢? 我们举个比较难复制的对象:皇帝  中国的历史上很少出现两个皇帝并存的时期,是有,但不多,那我们就认...

宇智波带土 217

23种设计模式(五) —— 手写实现 Singleton 模式 (生成实例)

手写单例模式

欢迎来到Gorit的博客 1524

Java SE 第25讲 23种设计模式之单例模式(Singleton)

Design Pattern(设计模式) 单例模式(Singleton):表示一个类只会生成唯一的一个对象 设计模式是一种思想,是解决问题的一种方式。设计模式大量依托于多态 简单的单例模式实现如下: public class SingletonTest { public static void main(String[] args) { Singleton singleton = Sing...

FlyingLion的博客 149

单例模式——举例说明Java23种设计模式中的单例模式

单例模式——举例说明Java23种设计模式中的单例模式1. 概述2. 创建单例模式的方式2.1 饿汉式2.1.1 饿汉式(静态常量)2.1.2 饿汉式(静态代码块)2.2 懒汉式2.2.1 懒汉式(线程不安全)2.2.2 懒汉式(线程不安全,同步代码块)2.2.3 懒汉式(线程安全,同步方法)2.3 双重检查锁DCL(double checked locking)机制2.3.1 代码如下:2.3.2 分析优缺点2.3.3 关于 volatile 关键字2.4 静态内部类2.5 枚举3. JDK单例应用举例

@素素~的博客 520

拿到offer了,面试总结之——23种Java设计模式

【背景说明】 情人节那天网投了16家公司,第二天下午一家邀约面试,今天面试完就拿到offer了,准备些入职资料以及体检报告,下周上班。 托情人节的福,拿到offer的同时,接到另一家的面试邀约。还是准备准备明天去看看情况,呵呵。。。   【面试总结】 虽然拿到offer,但感觉面试过程中,技术方面的问答自己并不满意,其实问题不难,稍微准备一下就可以了,或许开发中用得少了,结果一时短路,回...

梦开始的地方 720
上一篇: java23种设计模式之简介
下一篇: java23种常用设计模式之适配器模式(Adapter)
freedom1993
博客等级 码龄12年 25粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值