java中双检锁为什么要加上volatile关键字!
来源:互联网 发布:javascript入门经典pdf 编辑:程序博客网 时间:2024/06/07 05:38
单线程版本:
class Foo { private Helper helper = null; public Helper getHelper() { if (helper == null) helper = new Helper(); return helper; } // other functions and members... }
多线程版本(正确的):
class Foo { private Helper helper = null; public synchronized Helper getHelper() { if (helper == null) helper = new Helper(); return helper; } // other functions and members... }多线程版本(错误的):
class Foo { private Helper helper = null; public Helper getHelper() { if (helper == null) synchronized(this) { if (helper == null) helper = new Helper(); } return helper; } // other functions and members... }
使用volatile关键字修改版:
class Foo { private volatile Helper helper = null; public Helper getHelper() { if (helper == null) { synchronized (this) { if (helper == null) helper = new Helper(); } } return helper; }}
为什么不加volatile的双检锁是不起作用的?
The most obvious reason it doesn't work it that the writes that initialize the Helper object and the write to the helper field can be done or perceived out of order. Thus, a thread which invokes getHelper() could see a non-null reference to a helper object, but see the default values for fields of the helper object, rather than the values set in the constructor.
If the compiler inlines the call to the constructor, then the writes that initialize the object and the write to the helper field can be freely reordered if the compiler can prove that the constructor cannot throw an exception or perform synchronization.
Even if the compiler does not reorder those writes, on a multiprocessor the processor or the memory system may reorder those writes, as perceived by a thread running on another processor.
在给helper对象初始化的过程中,jvm做了下面3件事:
1.给helper对象分配内存
2.调用构造函数
3.将helper对象指向分配的内存空间
由于jvm的"优化",指令2和指令3的执行顺序是不一定的,当执行完指定3后,此时的helper对象就已经不在是null的了,但此时指令2不一定已经被执行。
假设线程1和线程2同时调用getHelper()方法,此时线程1执行完指令1和指令3,线程2抢到了执行权,此时helper对象是非空的。
所以线程2拿到了一个尚未初始化的helper对象,此时线程2调用这个helper就会抛出异常。
为什么volatile可以一定程度上保证双检锁ok?
- java中双检锁为什么要加上volatile关键字!
- java 关键字volatile
- Java中的volatile关键字
- Java中的volatile关键字
- JAVA:volatile关键字
- Volatile 关键字 java
- Java中的volatile关键字
- Java线程:volatile关键字
- Java线程:volatile关键字
- Java中的volatile关键字
- Java线程:volatile关键字
- Java中的volatile关键字
- Java线程:volatile关键字
- Java中的volatile关键字
- java的关键字volatile
- Java中的volatile关键字
- Java Volatile 关键字
- 温故而知新:Java volatile 关键字
- 【集体智慧编程】第三章、发现群组
- 窗口右小角弹出方式(窗口弹出)
- httpclient4.4 http摘要认证请求
- Java GC笔记
- 如何查看linux是否支持cfg80211
- java中双检锁为什么要加上volatile关键字!
- Centos上安装使用Jenkins
- ansysworkbench材料性能假设与指标
- 计算机英语·E
- linux书单
- androidstudio配置lambda表达式
- Effective C++ 读书笔记六
- QT文件查找
- 有关小波的几个术语及常见的小波基介绍