李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
单例模式volatile分析
Leefs
2020-02-21 AM
1909℃
0条
# 单例模式volatile分析 ### 概述 **DCL(双端检锁)机制不一定线程安全,原因是有指令重排序的存在,加入volatile可以禁止指令重排** 原因在于某一个线程执行到第一次检测,读取到instance不为null时,instance的引用对象可能没有完成初始化。 > instance = new SingletonDemo();可以分为以下3步完成 > > + memory = allocate();//1.分配对象内存空间 > + instance(memory);;//2.初始化对象 > + instance = memory;//3.设置instance指向刚分配的内存地址,此时instance != null 步骤2和步骤3不存在数据依赖关系,而且无论重排前还是重排后程序的执行结果在单线程中并没有改变,因此这种重排序优化是允许的。 > + memory = allocate();//1.分配对象内存空间 > + instance = memory;//3.设置instance指向刚分配的内存地址,此时instance != null 对象还没有初始化完成 > + instance(memory);;//2.初始化对象 但是指令重排只会保证串行语义的执行的一致性(单线程),但并不会关心多线程间的语义一致性。 **所以当一条线程访问instance不为null时,由于instance实例未必已初始化完成,也就造成了线程安全问题。** **完整代码** ```java public class SIngletonDemo { private static volatile SIngletonDemo instance = null; private SIngletonDemo(){ System.out.println(Thread.currentThread().getName()+"构造方法"); } public static SIngletonDemo getInstance(){ if(instance == null){ synchronized(SIngletonDemo.class){ if(instance == null){ instance = new SIngletonDemo(); } } } return instance; } public static void main(String[] args) { for(int i=1;i<=100;i++){ new Thread(()->{ SIngletonDemo.getInstance(); },String.valueOf(i)).start(); } } } ``` **运行结果** ``` 1构造方法 ```
标签:
设计模式
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/635.html
上一篇
【转载】单例模式简介
下一篇
CAS简介
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
Golang基础
容器深入研究
CentOS
锁
RSA加解密
Python
Docker
正则表达式
散列
Kibana
gorm
VUE
SpringBoot
Azkaban
排序
Linux
人工智能
HDFS
LeetCode刷题
Java工具类
Hive
ClickHouse
Quartz
Redis
Spark SQL
二叉树
设计模式
Spring
Java阻塞队列
Scala
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭