【线程安全】—— 单例类双重检查加锁(double-checked locking)
1. 三个版本单例类的实现
版本1:经典版
public class Singleton {
public static Singleton getInstance() {
if (instance == null) {
// 进入 if 之后(也就是 instance 为空时),此时如果另外一个进程刚好执行到 instance = new Singleton(); 则破坏了单例类的唯一性;
instance = new Singleton();
}
return instance;
}
private Singleton() {}
private static Singleton instance;
}缺陷:非线程安全,当一个线程进入 getInstance() 方法的 if 判断,而未创建赋值新的对象实例之前,另外一个线程进入 if 判断,将产生两个“单例”对象;
版本2:同步版
public class Singleton {
public static synchronized Singleton getInstance () {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}synchronized 关键字保证了,每一个方法进入该方法之前,都要等到其他方线程离开该方法。
该方法的缺陷在于,低效。事实上,只在第一次实例化对象时,需要加锁,或者叫同步(版本2方法,每次都要进行加锁验证)。后续获取实例时,多个线程是可以进入同时进入该方法的,因为 if 判断必然通不过,直接返回单例实例。
版本3:双重检查加锁:
public class Singleton {
private volatile static Singleton instance;
public static Singleton getInstance () {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
2. 使用 lock 机制(C++ 版)
class Singleton {
private:
volatile Singleton* pInst = 0;
public:
static Singleton* GetInstance() {
if (pInst == 0) {
lock();
if (pInst == 0) {
pInst = new Singleton();
}
unlock();
}
return pInst;
}
}
同步机制(synchronized)等价于锁机制;
【线程安全】—— 单例类双重检查加锁(double-checked locking)的更多相关文章
- muduo网络库源码学习————线程本地单例类封装
muduo库中线程本地单例类封装代码是ThreadLocalSingleton.h 如下所示: //线程本地单例类封装 // Use of this source code is governed b ...
- C#单例类的实现
C#单例类的实现 单例类保证一个类全局仅有一个实例,并提供一个全局访问点,由于只能生成一个实例,因此我们必须把构造函数设为私有函数以禁止他人创建实例. 实现1:懒汉式,线程不安全 该实现没有额外开销, ...
- 单例---被废弃的DCL双重检查加锁
被废弃的单例的DCL双重检查加锁/* *单例模式 *单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点. *加同步锁的单例模式,适合在多线程中使用. */ class Singleton{ ...
- java双重检测或枚举类实现线程安全单例(懒汉模式)
双重检测实现 /** * 懒汉模式->双重同步锁单例模式 */ public class SingletonExample5 { private SingletonExample5() { } ...
- c++:自己动手实现线程安全的c++单例类
前段时间使用c++做项目开发,需要根据根据配置文件路径加载全局配置文件,并对外提供唯一访问点.面对这样一个需求,自然的就想到了使用单例模式来创建一个单例配置对象,供外部调用.一开始想使用boost中自 ...
- Java线程和多线程(五)——单例类中的线程安全
单例模式是最广泛使用的创建模式之一.在现实世界之中,诸如Databae的连接或者是企业信息系统(EIS)等,通常其创建都是受到限制的,应该尽量复用已存在对象而不是频繁创建销毁.为了达到这个目的,开发者 ...
- Java单例类的简单实现
对于java新手来说,单例类给我的印象挺深,之前一道web后台笔试题就是写单例类.*.*可惜当时不了解. 在大部分时候,我们将类的构造器定义成public访问权限,允许任何类自由创建该类的对象.但在某 ...
- 设计模式——懒汉式单例类PK饿汉式单例类
前言 我们都知道生活中好多小软件,有的支持多IP在线,有的仅仅局限于单个IP在线.为什么这样设计,在软件开发阶段就是,有需求就是发展.这就是软件开发的一个设计模式--懒汉式单例类和饿汉式单例类. 内容 ...
- 游戏设计模式——C++单例类
前言: 本文将探讨单例类设计模式,单例类的懒汉模式/饿汉模式,单例类的多线程安全性,最后将利用C++模板减少单例类代码量. 本文假设有一个Manager管理类,并以此为探究单例类的设计模式. 懒汉模式 ...
随机推荐
- 梦想MxWeb3D,三维CAD协同设计平台 2019.04.09更新
SDK开发包下载地址: http://www.mxdraw.com/ndetail_10140.html 在线演示网址: http://www.mxdraw.com:3000/ 1. 增加上传dwg ...
- 12Oracle Database SQL程序
Oracle Databse SQL 程序 程序块 在这之前,我们所有的sql语句都是一句一句执行的,如果我们把很多事情看作一个整体提交执行的话,必须使用程序块. 声明部分:声名变量及初始化 关键字: ...
- 了解固态硬盘SSD,竟然如此简单!小白也能懂!
https://www.youtube.com/watch?v=alb6-zp52mA
- java基础学习日志---File方法分析
package FunDemo; import java.io.File; import java.io.IOException; import java.util.Arrays; public cl ...
- Python数据分析与展示(1)-数据分析之表示(1)-NumPy库入门
Numpy库入门 从一个数据到一组数据 维度:一组数据的组织形式 一维数据:由对等关系的有序或无序数据构成,采用线性方式组织. 可用类型:对应列表.数组和集合 不同点: 列表:数据类型可以不同 数组: ...
- Batchelor Prize
awards in fluid mechanics The Prize of $25,000 is awarded every four years to a single scientist for ...
- 3.3.3 char 类型
char类型原本用于表示单个字符.不过,现在情况已经有所变化.如今,有些Unicode字符可以用一个char值描述,另外一些Unicode字符则需要两个 char 值. char类 ...
- Vue2.0如何自定义时间过滤器
我们知道Vue2.0开始不再支持自带的过滤器,需要我们自己去自定义过滤器,方法如下: 我们可以自己定义一个时间过滤器,在此引用了一个日期处理类库(Moment.js)可以很快的实现 ...
- 【DIP, OpenCV】Some Kinds Of Image Smoothing Methodologies
In digital image processing(DIP), many methods are used in smoothing images in order to suppress noi ...
- 百练4103:踩方格(DFS)
描述 有一个方格矩阵,矩阵边界在无穷远处.我们做如下假设:a. 每走一步时,只能从当前方格移动一格,走到某个相邻的方格上:b. 走过的格子立即塌陷无法再走第二次:c. 只能向北.东. ...