单例模式初探

当我们在系统中需要频繁使用一个公用的类的时候,我们更多的希望不用每次在调用的时候去实例化一个新的对象。在设计模式当中有这样一种设计模式——单例模式。

单例模式可以简单的分为饥汉模式和懒汉模式,我们来分别看一下两种模式的实现方式吧:

饥汉模式:

public class PrintMessage {

	private static PrintMessage pm = new PrintMessage();
	/**
	 * 私有化构造函数
	 */
	private PrintMessage(){}
	/**
	 * 获取全局唯一实例
	 * @return
	 */
	public synchronized static PrintMessage getInstance(){
		return pm;
	}
}

  懒汉模式:

 

public class PrintMessage {
	private static PrintMessage pm = null;
	/**
	 * 私有化构造函数
	 */
	private PrintMessage(){}
	/**
	 * 获取全局唯一实例
	 * @return
	 */
	public synchronized static PrintMessage getInstance(){
		if(pm == null){
			pm = new PrintMessage();
		}
		return pm;
	}
}

 

  两种模式可以同样实现在内存中生成唯一的对象,不过两者之间存在一定的区别,饥汉模式会在类装载的时候生成全局的唯一变量,而懒汉模式会在系统首次调用的时候生成全局唯一变量,一个是在系统初始化的时候耗费生成实例的时间,一个是在首次调用的时候耗费生成实例的时间。不过具体要看情况而选择不同的模式。

懒汉模式潜在中存在一定的危险性,当然这种危险性是相对的,就是假设在多个线程第一次同时调用该类,那么存在一种可能是生成多个对象,违反了单例的原则,不过这种可能性极低。我们有时候完全不必要考虑为了避免这一点安全性来给类加上更耗费资源的同步锁问题。

说到上面的同步,单例模式其实也存在一个多线程同步问题,因为单例的实现,目的就是在多线程调用情况下不过多的生成新的实力耗费资源。我们来看下面一段代码,代码用单例模式编写,顺序打印出一堆数据。

 

public class PrintMessage {
	private static PrintMessage pm = null;
	private int count = 0 ;
	/**
	 * 私有化构造函数
	 */
	private PrintMessage(){}
	/**
	 * 获取全局唯一实例
	 * @return
	 */
	public static PrintMessage getInstance(){
		if(pm == null){
			pm = new PrintMessage();
		}
		return pm;
	}
	/**
	 * 打印信息
	 * 
	 */
	public void print() {
		System.out.println(count);
		/*try {
			Thread.currentThread().sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}*/
		count++;
		
	}
}

 

  我们再模拟一个多线程去调用这个单例。看下输出结果:

 

public static void main(String[] args){
		for (int i = 0; i < 50; i++) {
			Thread t = new Thread(
			new Runnable(){
				public void run(){
					PrintMessage.getInstance().print();	
				}
			}		
			);
			t.start();
		}
	}

 

  我们可以很容易的看到打印出的结果有很多重复数据,我想大家应该可以看出来是典型的线程同步的问题。那么我们怎么避免这个问题呢?首先我想到再getInstance方法加上同步,同时只有一个对象获取该对象的实例。我们来看下下面的代码

 

public synchronized static PrintMessage getInstance(){
		if(pm == null){
			pm = new PrintMessage();
		}
		return pm;
	}

 

  继续执行多线程方法,我们发现结果依然不是我们希望的顺序递增。这是为什么呢?因为我们获取对象实例后,实际上已经获得了对象的一个映射,这是我们会释放该方法上的同步锁。所以依然没有对print方法起到同步的效果。我们来看下给print方法加上同步锁呢。

 

/**
	 * 打印信息
	 * 
	 */
	public synchronized void print() {
		System.out.println(count);
		/*try {
			Thread.currentThread().sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}*/
		count++;
		
	}

  继续执行先前的方法,怎么样,可以看到我们希望的顺序递增的效果了吧。当然不知道理解对不对,但是单例模式中的线程安全问题还是需要特别注意的。

 

Python调用CANoe(1)(启动与停止,变量和信号读写) CANoe因为其封闭性(Vector独有),开发的时候,有很多局限性;Python 因为其开源,容易上手,功能强大,那么Python 和 CANoe结合会产生怎样的火花呢? 阅读详情

相关推荐

工业金属表面缺陷检测:4种光学成像方案(明/暗/漫/背光)选型与实测对比

本文深入探讨工业金属表面缺陷检测中的4种光学成像方案(明/暗/漫/背光),详细解析其物理原理、适用场景及实测效果。通过对比不同照明方案在铝合金轮毂、不锈钢餐具等实际工业场景中的表现,提供科学的选型决策树,帮助提升缺陷检出率至99%以上,为计算机视觉在工业质检领域的应用提供实用指南。

weixin_33624741的博客 388

iOS之单例模式初探

单例模式可能是设计模式中最简单的形式了,这一模式的意图就是使得类中的一个对象成为系统中的唯一实例。它提供了对类的对象所提供的资源的全局访问点。因此需要用一种只允许生成对象类的唯一实例的机制。下面让我们来看下单例的作用: 可以保证的程序运行过程,一个类只有一个示例,而且该实例易于供外界访问从而方便地控制了实例个数,并节约系统资源。 单例模式的使用场合 类只能有一个实例,并且必须从一

xiaoxuan415315的专栏 522

WhatsApp API接口的隐秘角落:从协议解析到自定义消息引擎

本文深入解析WhatsApp API接口的隐秘角落,从协议逆向工程到自定义消息引擎开发实战。通过分析WhatsApp的二进制XML协议和加密机制,构建超越官方API限制的自定义消息引擎,实现高效、灵活的即时通讯解决方案。文章还提供了企业级架构设计和风控规避策略,助力开发者突破官方限制,提升消息到达率和成本效益。

q3r4s5t的博客 761

Android开发之单例模式初探

单例模式是什么呢?是Java23中模式之一,在Android开发中也有着广泛的运用,比如Calander类,在创建对象的时候并不是通过 new Calander而是Calander.getInstnce(),这就是单例模式的一种运用,应用的场合是什么呢?我们在很多时候有些对象只需要一个就够了,并不需要多个,就比如古代的皇帝,一山不容二虎,老虎多了只有坏处没有好处。它的作用就是保证整个应用程序中某个

林泓成的专栏 1734

黑客渗透测试后门隐藏技术揭秘

本文介绍了在授权渗透测试中隐藏后门文件(muma.exe)的多种技术手段。主要包括:通过WinRAR自解压脚本将后门与正常程序捆绑实现双开;利用系统自动运行目录和注册表实现开机自启;修改文件图标伪装成常用软件;将文件存放在冷门系统目录;设置系统+隐藏双重属性增强隐蔽性。此外还涉及对抗安全软件的加壳(UPX)、免杀(msfvenom编码)技术,以及进程注入、日志清除等运行隐藏方法。所有技术仅限合法授权测试使用,未经授权使用将面临法律责任。

m0_60781580的博客 1040

R语言dlnm包避坑指南:手把手教你配置交叉基矩阵(附温度分层与滞后多项式设置)

本文详细介绍了R语言dlnm包在配置交叉基矩阵时的实用技巧与避坑指南,特别针对温度分层与滞后多项式设置提供了具体参数配置建议。通过解析`crossbasis()`函数的核心参数、温度分析的分层策略以及不同基函数的适用场景,帮助研究者高效构建分布滞后非线性模型,避免常见错误并优化模型性能。

weixin_34094282的博客 401

设计模式初探之单例模式

设计模式初探之单例模式 单例模式概念: ​ 单例模式一种常见得设计模式,顾名思义就是只能有一个实例。 单例模式应用场景: ​ 线程池、缓存、日志对象以及各种配置的读取。 单例模式实现方法: 懒汉模式:能实现懒加载,但是在并发情况下使用synchronized 对性能有所影响。 饿汉模式:不能懒加载,消耗较大,在并发情况下是线程安全的。 Holder模式:饿汉模式和懒汉模式的组合,既实现了懒汉模式的懒加载又实现了饿汉模式的安全性,而且没有使用synchronized 性能得到了保证,同时也是工作中常用的方式

m0_47372765的博客 222

QGIS效率提升神器:qgis_mcp插件+VSCode联合工作流配置全解析

本文详细解析了如何通过配置qgis_mcp插件与VSCode的联合工作流,实现语音控制和代码自动化来大幅提升QGIS操作效率。该方案将自然语言交互与现代编辑器生态结合,为地理信息专业人士构建了智能、高效的全新工作模式,彻底改变传统GIS操作方式。

weixin_29228203的博客 191

初探单例模式

私有的构造函数   私有的静态字段    包含实例化的对象(自己本身)           例子       class   Person {        private static Person instance = new Person;        public Person   GetPerson    //只能通过该属性获得对象 又由于对象时静态的所以

yuchang2012的专栏 454

全球第一开源云ERP Odoo操作手册 模块安装和界面汉化指南

Odoo 的功能包含在不同的模块中, 刚创建的数据库除 Odoo 的核心模块外, 其它模块并没有被安装到系统中,你可以根据需要安装它们。本节将介绍安装模块和界面汉化的相关知识。

weixin_44793763的博客 2073

手把手教你学Simulink——基于核能发电系统的场景实例:核电站汽轮机与发电机协调控制仿真

在核电机组中,汽轮机-发电机系统是将核能最终转化为电能的关键环节。与火电机组不同,核反应堆的热惯性大、功率调节慢,因此汽轮机的控制策略需与反应堆特性相匹配,实现安全、稳定、高效的能量转换。维持发电机输出功率/频率稳定(响应电网调度)调节汽轮机进汽压力(匹配一回路蒸汽供应)实现“堆-机协调控制”保障机组在启停、变负荷、甩负荷等工况下的安全性本教程将带你使用构建一个核电站汽轮机与发电机协调控制系统汽轮机调速系统(调门控制)建模发电机与电网接口建模(同步机)

MHD0815的博客 212

python单例模式解析_Python单例模式初探

在前一篇blog中我们提到了logging模块中的root logger是单例模式的,所以紧接着我们就来探索一下单例模式在python中的实现。什么是单例模式(singleton)单例模式是一种对于创建对象行为的设计模式,该模式要求一个类只能创建并存有一个实例化对象。而为什么使用单例模式呢?单例模式是为了避免不必要的内存浪费,如多个线程调用一个类,但实际并不需要对每个线程都提供一个该类的实例;同样...

weixin_39791446的博客 175

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

设计模式初探-单例模式

Singleton模式,又称单例模式,它保证一个类仅有一个实例,并提供一个访问它的全局访问点。单例模式在平常开发中经常用到,比如系统的全局配置属性,常用的工具类或工厂方法都可以实现为一个单例。单例模式概念很简单,实现起来也不麻烦,但一不小心还是有可能出错的。 一、使用场景 只要是要求实例唯一的都可以使用单例模式来实现,特别是耗资源的实例! 二、UML图 三、Java实现 1、懒汉

Java Dynamic的专栏 1726

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

c++单例模式初探

在cocos2d-x中看到了大量的单例模式,于是学习了一下c++的单例模式。 单例模式是什么?      只能产生一个实例的类就是单例模式。我们设计一个类,有时只需要使用它一次,比如一台电脑只能有一个显示器,日志的输出,窗口只能有一个,于是我们通过单例模式来实现它,而非全局变量,因为全局变量会影响封装性,不能保证程序不会修改它。 c++单例模式如何实现?      实现单例模式要注

l-jobs的专栏 560

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

设计模式初探——单例模式

所谓的单例模式就是指的一个类只提供一个对象实例,而且所提供的实例只有一个访问的入口(方法)。 常见的应用场景: Windows的任务管理器 Windows的回收站 项目中,读取配置文件的类,一般也只有一个对象。 数据库连接池的设计等等。 常见的有五种实现方式: 饿汉式 所谓的饿汉式就是,让单例对象在类创建时就被加载,像一个饿汉。 package cn.liu.si...

MADE_哒哒 155

设计模式初探—单例模式

什么是设计模式? 是一套被反复使用,多数人知晓的,经过分类编目,代码设计经验的总结。 设计模式的作用? 使用设计模式是为了可重用代码,让代码更容易让他人理解,保证代码可靠性。 单例模式: 有些对象我们只需要一个,如果创造出多个实例,就会导致许多问题,比如占用过多资源,不一致的结果等。单例模式就是保证整个应用中某个实例有且只有一个。 常用的单例的模式主要有两种:饿汉模式和懒汉模式 ...

A cold winter的博客 172

初探设计模式之单例模式

设计模式是解决某一类问题最行之有效的方法。

hejin17909mm的专栏 369

JS设计模式初探——单例模式

​ 所谓单例,即整个系统中只存在某个类的一个单一实例。​ 单例模式是一种比较常见的设计模式,它也被应用在许多场景,它能够解决如下问题:命名空间管理:可以将一组有关联的属性和方法封装到一个单例中,方便命名管理,防止这些方法属性和其他类的实例的方法属性发生命名冲突。资源共享,由于有些实例的内存损耗比较大,一旦有多个实例,内存损耗就会非常严重,这时候,就可以使用单例模式来保证实例的唯一性,即每次调用和创建实例返回的都是内存中的同一个实例。保证实例的唯一性:有些实例整个系统中只能存在一个,否则会引起同步问题和操作冲

林中路 443

初探单例模式学习笔记

如何防止一个类产生多个实例呢 1.不做任何措施

wangxiaobupt的专栏 1129
上一篇: 快速排序
下一篇: 20100105小记——囧事
refactaar
博客等级 码龄17年 0粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值