Double check 双重检查实现单例模式
java
it书童
2020-12-26 18:29:51
0赞
0踩
99阅读
0评论
代码如下:
public class LazyDoubleCheckSingleton {
private volatile static LazyDoubleCheckSingleton lazyDoubleCheckSingleton;
private LazyDoubleCheckSingleton() {
}
public static LazyDoubleCheckSingleton getInstance() {
if (lazyDoubleCheckSingleton == null) { // 这层判断,可以大幅度减少 synchronized 在方法上造成的开销
// 锁定了该类
synchronized (LazyDoubleCheckSingleton.class) {
if (lazyDoubleCheckSingleton == null) {
lazyDoubleCheckSingleton = new LazyDoubleCheckSingleton();
// 实例化代码的三个步骤 实际过程,2 和 3 可能会倒置
// 1.分配内存给这个对象
// 2.初始化对象
// 3.设置 LazyDoubleCheckSingleton 指向刚分配的内存地址
}
}
}
return lazyDoubleCheckSingleton;
}
}
Double check 是为了兼顾性能与安全,不必每次都直接加锁,加锁是有成本的。
用两个判断的原因:
同步锁外判断,为避免在实例已经创建的情况下每次获取实例都加锁取,影响性能;
锁内判断,考虑多线程情况下,两个以上线程都已经运行至同步锁处,也就是都已经判断变量为空,如锁内不再次判断,会导致实例重复创建
此外还要防止实例化内存的重排序导致的隐患
实例化代码的三个步骤 实际过程,2 和 3 可能会倒置
1.分配内存给这个对象
2.初始化对象
3.设置 LazyDoubleCheckSingleton 指向刚分配的内存地址
2 和 3 的重排序并不会影响最终结果
如果是多线程可能就有以下隐患
解决:使用 volatile 关键字,不允许2和3重排序
- 上一篇: 单例模式-懒汉式实现
- 下一篇: 静态内部类实现单例模式

关于我
一个文科出身的程序员,追求做个有趣的人,传播有价值的知识,微信公众号主要分享读书思考心得,不会有代码类文章,非程序员的同学请放心订阅
转载须注明出处:https://www.itshutong.com/articles/1009
精品付费
个人开发者通过payjs接入微信支付
2582
0
这一次,真正掌握composer
1509
0
相关推荐
Tomcat 入门详解
178
0
java 接口中的常量
165
0
Java 类的继承与接口实现的区别
165
0
Java 面向对象的多态特征介绍
180
0
Java 线程等待唤醒机制
138
0
Java 属性集
162
0
SpringBoot 入门程序
143
0
负载均衡 Ribbon 入门
172
0
Lambda表达式的几种简化写法
139
0