【线程安全】—— 单例类双重检查加锁(double-checked locking)
2024-08-31 00:33:35
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)等价于锁机制;
最新文章
- Android观察者模式的简单实现demo
- ListView组件应用源码
- Notepad++ 开启「切分窗口」同时检视、比对两份文件
- C#引用C++代码
- J2EE 第二阶段项目之编写代码(四)
- [转]DllMain中不当操作导致死锁问题的分析——DllMain中要谨慎写代码(完结篇)
- VS2015 Cordova Ionic移动开发(五)
- Fishnet(计算几何)
- sql server 修改字段大小
- 客户端把rsyslog重启,就会发送全部日志 --待研究
- UESTC_How many good substrings CDOJ 1026
- kill -QUIT <;pid>;
- JS基础速成(二)-BOM(浏览器对象模型)
- Centos7 HyperLedger Fabric 1.4 生产环境部署
- 使用commons.cli实现MyCP
- 在IE浏览器中url传参长度问题
- hbase 存储结构和原理
- Ajax基本语法
- 在ServiceModel客户端配置部分中,找不到引用协定“”的默认终结点元素
- 元组类型&;字典类型