JVM资料整理java面试java基础

volatile关键字作用及原理

2017-04-13  本文已影响126人  Mars_M

volatile的作用

volatile的两层语义:

1、volatile保证变量对所有线程的可见性:当volatile变量被修改,新值对所有线程会立即更新。或者理解为多线程环境下使用volatile修饰的变量的值一定是最新的。

2、jdk1.5以后volatile完全避免了指令重排优化。

volatile使用场景

volatile可以部分取代synchronized,作为一个轻量级的读安全锁,但是并非写入安全。

使用volatile必须满足:

1、运算结果不依赖当前值,或者说确保只有单一线程能修改volatile的值。

例如多线程对某个变量自增操作,会导致实际上很多自增作废无法写入。

2、变量不需要与其他的状态变量共同参与不变约束。

volatile的底层实现原理是什么?

获取JIT(即时Java编译器,把字节码解释为机器语言发送给处理器)的汇编代码,发现volatile多加了lock addl指令,这个操作相当于一个内存屏障,使得lock指令后的指令不能重排序到内存屏障前的位置。这也是为什么JDK1.5以后可以使用双锁检测实现单例模式。

lock前缀的另一层意义是使得本线程工作内存中的volatile变量值立即写入到主内存中,并且使得其他线程共享的该volatile变量无效化,这样其他线程必须重新从主内存中读取变量值。

关于处理器指令重排

指令重排序是JVM为了优化指令,提高程序运行效率。指令重排序包括编译器重排序和运行时重排序。JVM规范规定,指令重排序可以在不影响单线程程序执行结果前提下进行。

关于DCL双锁检测

在JDK1.5前使用volatile,或者不使用volatile修饰单例,会导致引用返回后对象并未初始化完毕就释放了锁,而jdk1.5后加入volatile即加入了内存屏障,对象的初始化必须完成后才能给变量赋值。这样就不存在指令重排优化后的缺陷。

volatile的性能

读操作与普通变量无差别,写操作会慢一些,大多情况比锁消耗低。

上一篇下一篇

猜你喜欢

热点阅读