线程安全 单例模式

单例模式的线程安全 前言 单例模式(Singleton)几乎是人尽皆知的设计模式了,它限制一个对象只能实例化一次,且该对象的生命周期一般与整个应用的生命周期一致(否则,单例模式完全可以被普通类对象替代)。单例对象应该允许多线程访问,确保单例对象是线程安全的十分有必要。 单例由于其生命周期特点,一般被实现为指针对象或静态对象,下面将分别讨论这两种情况的线程安全实现。 静态指针变量 下面实现一个基本的单例对象: // Example 1 class Singleton { private: Singleton() = de 阅读详情

线程安全-单例模式

线程安全性的定义:
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。 
  或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。

线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。

多线程环境下写代码的时候要注意这个问题,说白了它是一个并发的问题。asp.net程序也要注意这个问题,许多用户同时访问,进行同一个操作的时候,如果不注意这个问题,将会导致数据库数据出错。一些关键性的地方要用事务来处理数据库的更改操作。前面老是看到这个名词,一直懒的看看它到底是怎么回事,原来就是并发操作的问题。

单例(Singleton)模式下最关心的就是这个线程安全的问题了,介绍一个单例模式:
单实例设可能是使用最广泛的设计模式。其思想意图是保证一个类只有一个实例,并且提供类对象的全程访问。单实例对象应用的范围很广:如GUI应用必须是单鼠标,MODEM的联接需要一条且只需要一条电话线,操作系统只能有一个窗口管理器,一台PC连一个键盘。使用全程对象能够保证方便地访问实例,但是不能保证只声明一个对象-也就是说除了一个全程实例外,仍然能创建相同类的本地实例。单实例模式通过类本身来管理其唯一实例,这种特性提供了问题的解决办法。唯一的实例是类的一个普通对象,但设计这个类时,让它只能创建一个实例并提供对此实例的全程访问。唯一实例类Singleton在静态成员函数中隐藏创建实例的操作。

单例模式在java和C#里有两个实现方式:1、懒汉模式(lazy initialization);2、饿汉模式
以下是C#伪代码(摘自网络)
1、懒汉模式
using System; 
namespace csPattern.Singleton 
{ 
public class Singleton 
{ 
static Singleton uniSingleton; 
private Singleton() {} 
static public Singleton instance() 
{ 
if (null == uniSingleton) 
{ 
uniSingleton = new Singleton _lazy(); 
} 
return uniSingleton; 
} 
} 
}

2、饿汉模式
using System; 
namespace csPattern.Singleton 
{ 
public class Singleton 
{ 
static Singleton uniSingleton = new Singleton(); 
private Singleton() {} 
static public Singleton instance() 
{ 
return uniSingleton; 
} 
} 
}

两种实现模式的比较:
1、相同点:两种方式的构造函数都是私有的,对外的接口都是工厂方法
2、不同点:饿汉式是在类装载的时候直接得到该类的实例,可以说是前期绑定的;懒汉式是后期绑定的,类加载的时候uniSingleton是空的,在需要的时候才被创建且仅创建一次。饿汉式的速度快,效率高,但是耗费系统资源;懒汉式则相反。懒汉式还存在一个问题,就是后期绑定不能确保对象只能被实例化一次,这需要对指示类是否实例化的标志设置1个互斥锁,仅允许1个线程访问。这样就可以确保对象只被实例化一次。

懒汉模式的具体实现C#代码
using System; 
using System.Threading; 
using System.Runtime.CompilerServices; 
namespace csPattern.Singleton 
{ 
public class Counter_lazy 
{ 
static Counter_lazy uniCounter; 
private int totNum = 0; 
private Counter_lazy() 
{ 
Thread.Sleep(100); //假设多线程的时候因某种原因阻塞100毫秒 
} 
[MethodImpl(MethodImplOptions.Synchronized)] //方法的同步属性 
static public Counter_lazy instance() 
{ 
if (null == uniCounter) 
{ 
uniCounter = new Counter_lazy(); 
} 
return uniCounter; 
} 
public void Inc() { totNum ++;} 
public int GetCounter() { return totNum;} 
} 
}

   不知道大家有没有注意到instance()方法上方的[MethodImpl(MethodImplOptions.Synchronized)] 语句,他就是同步的要点,他指定了instance()方法同时只能被一个线程使用,这样就避免了线程0调用instance()创建完成实例前线程1就来调用instance()试图获得该实例。

   根据MSDN的提示,也可以使用lock关键字进行线程的加锁,代码如下:

using System; 
using System.Threading; 
namespace csPattern.Singleton 
{ 
public class Counter_lazy 
{ 
static Counter_lazy uniCounter; 
static object myObject = new object(); 
private int totNum = 0; 
private Counter_lazy() 
{ 
Thread.Sleep(100); //假设多线程的时候因某种原因阻塞100毫秒 
} 
static public Counter_lazy instance() 
{ 
lock(myObject) 
{ 
if (null == uniCounter) 
{ 
uniCounter = new Counter_lazy(); 
} 
return uniCounter; 
} 
} 
public void Inc() { totNum ++;} 
public int GetCounter() { return totNum;} 
} 
}

   lock()是对一个对象加互斥锁,只允许一个线程访问其后大括号中语句块,直到该语句块的代码执行完才解锁,解锁后才允许其他的线程执行其语句块。

   还可以使用Mutex类进行同步,定义private static Mutex mut = new Mutex();后,修改instance()如下,同样可以得到正确的结果:

static public Counter_lazy instance() 
{ 
mut.WaitOne(); 
if (null == uniCounter) 
{ 
uniCounter = new Counter_lazy(); 
} 
mut.ReleaseMutex(); 
return uniCounter; 
}

http://hi.baidu.com/daijun2007/blog/item/5d102f093c1319c83bc76300.html

避坑指南:麒麟系统ARM架构下PostGIS离线安装常见问题解析 本文深度解析了在国产麒麟系统ARM64架构下进行PostGIS离线安装的完整路径与核心避坑点。通过对比Docker容器化与源码编译两种部署方式的优劣,详细阐述了离线Docker环境搭建、ARM64镜像获取验证、容器化配置及常见故障排查的全流程,为在特殊环境下稳定部署空间数据库提供了一套可靠的实践指南。 阅读详情

相关推荐

ExoPlayer硬解码实战:如何绕过系统默认软解码提升播放性能(附完整代码)

本文深入剖析了ExoPlayer默认解码器选择机制的不确定性,并提供了通过自定义MediaCodecSelector强制启用硬解码的完整实战方案。该方案能有效解决因软解码导致的播放卡顿、黑屏花屏及高功耗问题,显著提升Android应用在各种设备上的视频播放性能与稳定性。

weixin_29295541的博客 456

<转>单例模式 线程安全

线程安全性的定义: 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。   或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。 线程安全问题都是由全局变量及静态变...

i54fx的专栏 252

移远EC20模块USB模式切换的底层逻辑与驱动适配探秘

本文深入探讨了移远EC20模块USB模式切换的底层逻辑与驱动适配机制,详细解析了AT命令控制下的USB0与WWAN0模式差异。通过分析USB协议栈、内核驱动框架及网络子系统的交互,提供了模式切换的完整操作流程和常见问题解决方案,助力开发者优化4G通信模块在嵌入式设备中的稳定连接。

cc789的博客 843

详解单例模式线程安全

各形式线程安全的单例模式

闰土的博客 1252

OpenCV实战(1)——OpenCV与图像处理基础

OpenCV 是一个跨平台计算机视觉和机器学习库,实现了图像处理和计算机视觉方面的很多通用算法。本节将介绍 OpenCV 的基础知识,以及如何编译运行 OpenCV 程序,并介绍如何完成最基本的图像处理任务——读取、显示和保存图像。除此之外,鼠标事件和图形绘制也是 OpenCV 计算机视觉项目中常用的基本功能,本节介绍了如何使用这两个重要的 OpenCV 功能。

盼小辉丶的博客 12万+

小卫星多普勒频偏MATLAB代码

多普勒频偏是由于发射机和接收机之间的相对运动而引起的频率变化。对于小卫星,由于其速度和高度的变化,多普勒频偏会变得更加明显。本文将探讨小卫星多普勒频偏的原理、影响因素以及补偿方法。多普勒频偏的原理当发射机和接收机之间存在相对运动时,接收到的信号频率会发生变化。这种频率变化称为多普勒频偏。其原理可以描述如下:设发射机和接收机之间的距离为 d,发射信号的频率为 f0,发射机和接收机的相对速度为 v。则接收到的信号频率 f 为:其中 c 为光速。

qq_59747472的博客 244

线程安全的几种单例模式

单例模式 单例模式是 Java 中常用的设计模式之一,属于设计模式三大类中的创建型模式。在运行期间,保证某个类仅有一个实例,并提供一个访问它的全局访问点。单例模式所属类的构造方法是私有的,所以单例类是不能被继承的。实现线程安全的单例模式有以下几种方式: 1.饿汉式 public class Singleton { private static Singleton instance = new Singleton(); private Singleton() { }

zzd007的博客 4864

基于WebRTC的现代在线视频会议系统设计与实现

本文详细介绍了如何使用Java和WebRTC技术构建一个完整的在线视频会议系统。我们将从WebRTC的基础原理讲起,逐步深入到信令服务器设计、媒体服务器配置、前后端实现以及高级功能的开发。文章包含大量代码示例和架构图,旨在为开发者提供一套完整的视频会议解决方案。关键词:WebRTC、视频会议、Java、Spring Boot、信令服务器、STUN/TURN、媒体服务器:获取摄像头和麦克风访问权限:处理点对点连接和流传输:实现浏览器之间的任意数据交换。

2201_76125393的博客 186

线程安全的单例模式

单例模式实现, Java实现线程安全的单例模式, 单例模式创建方法, 单例模式使用指南

yudian1991的博客 6656

脑机接口中的视觉信号解码:原理、技术与应用

脑机接口中的视觉信号解码:原理、技术与应用​ ,人工智能,计算机视觉,大模型,AI,脑机接口(Brain - Computer Interface,BCI)作为一种革命性的技术,致力于搭建人脑与外部设备之间的直接通信桥梁,绕开传统的神经肌肉输出通路。其核心目标是解读大脑活动产生的信号,从而实现对外部设备的精准控制或信息交互。在众多脑机接口研究方向中,视觉信号解码因其独特的优势和广泛的应用前景,吸引了大量科研人员的关注。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 20万+

多径衰落信道的 MATLAB 仿真

在无线通信系统中,信号在传输过程中会经历多径传播现象,导致信号在接收端出现时域和频域上的扩展。通过以上示例代码,我们可以进行多径衰落信道的 MATLAB 仿真。同时,我们还可以通过调整信道参数和信号特性,进一步研究多径衰落对系统性能的影响。常用的模型之一是瑞利衰落信道模型,它假设信号在传输过程中受到多个散射路径的影响。除了瑞利衰落信道模型,我们还可以使用其他类型的信道模型,如高斯衰落信道模型。在上述代码中,我们首先定义了信道的参数,包括最大多普勒频移、多径延迟和多径功率衰落。函数来模拟高斯衰落信道。

TechCraze的博客 665

单例模式中的线程安全问题

单例模式是面试中设计模式里考的最多的一个,本文就单例模式中的饿汉模式和懒汉模式中的线程安全进行说明,以及分别使用synchronized和双重校验锁使懒汉模式在多线程环境下为线程安全的

X_H学Java的博客 1万+

借助AI搞定国社科“研究内容”部分!用Gemini 3 Pro轻松撰写6大模块,让基金本子效率质量更上一层楼

所谓研究整体框架,是对课题研究逻辑结构与技术路径的系统阐述,其核心在于通过研究目标分解、研究内容模块化与研究方法整合,构建一个层次清晰、逻辑严密、科学可行的研究体系。撰写要求:1)分要点、分层次列出主要研究内容,保持各部分之间的逻辑性、层次性与系统性;研究可行性可理解为开展本课题在理论基础、研究方法、研究条件、人员结构、平台支撑及外部协作等方面的可实施程度,可从内部条件与外部条件两个维度进行系统论证。研究背景为:我正在申报xxx年xxx(项目名称),课题名称为:xxx,拟采用的主要研究方法包括:xxx等;

智能AI让学术科研更容易 964

线程安全之单例模式

这篇文章,我们会介绍一下单例模式,但这里的单例模式,不是我们所说的设计模式,当然听到设计模式,大家一定都说,我当然知道设计模式了,有23种呢?一下子一顿输出,当然我这里说的单例模式还是跟设计模式有一些区别的,当然我不做概述,因为我也没咋个去了解过设计模式,我把大家拉回来,什么是多线程对的单例模式呢?看完我以下的解释相信你会明白的.多线程环境下的单例模式需要保证只有一个实例对象被创建,并且可以在多线程环境下安全地访问该实例。

qq_44005305的博客 1955

VC中sqlite的使用

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

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

C++线程安全的单例模式总结

详细理解线程安全的单例模式

我的博客 1645

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

单例模式与线程安全

就是多个线程申请多个未释放的锁,然后他们各自却持有这些锁(未解锁),导致都需要等待对方释放,比如A线程持有锁a,B线程持有锁b,那B今天来申请锁A,A申请锁b,这样A,B线程都需要各自等待对方释放才能申请成功,跟那个shared_ptr的循环引用无法释放一样的道理。第⼀次调⽤GetInstance的时候,如果两个线程同时调⽤,可能会创建出两份T对象的实例, 但是后续再次调⽤,就没有问题了,此时inst就不是空了,不能创建对象了。⼀般⽽⾔,多个线程并发同⼀段只有局部变量的代码时,不会出现不同的结果。

2301_80377335的博客 989

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

单例模式介绍及单例模式的线程安全问题

单例模式是指对象在内存中只会创建且仅被创建一次的设计模式,这种设计模式被用来解决对象被频繁调用时的反复创建给设备带来较大负担的情况。

Leo521green的博客 1137

单例模式以及线程安全问题

单例模式以及解决线程安全问题

m0_74173529的博客 1492

单例模式是否线程安全

今天领导问了个问题说单例模式中,对象的变量是否是线程安全的。起初都不太确定,后来本着装的目的,试了一下,结果是否定的。在多线程环境下,对象的成员变量是不安全的。 [code="java"] package com.zhuyang.test; public class Singleton { private static final Singleton singleton; //...

zzzzzz55300411的博客 1935

单例模式的线程安全问题

我们在日常的开发过程中经常会遇到资源的共享的情况,如果每一个请求进来我们对单独的实例化一个对象势必会极大损耗我们系统的性能,那么我们如何去解决多线程资源共享的问题——一起来了解一下设计模式中的单例模式吧!

蹊源的奇思妙想的博客 2159

C#设计模式读书笔记之线程安全的单例模式(Singleton Pattern)

单例模式(Singleton Pattern)【使用频率:★★★★★】 1.概述: 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。 单例指的是只能存在一个实例的类,在C#中,更准确的说法是在每个AppDomain之中只能存在一个实例的类,它是软件工程中使用最多的几种模式之一。在第一个使用者创建了这个类的实例之后,其后需要使用这...

qq826364410的专栏 1321

线程安全版本的单例模式

饿汉单例模式 & 懒汉单例模式(确保线程安全)

2302_77459644的博客 1025
上一篇: MyEclipse时间显示问题
下一篇: 常用正则表达式
fly_buf
博客等级 码龄16年 7粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值