volatile 关键字
1、 volatile 翻译为 不稳定的,容易改变的。意思很明确,如果使用volatile 定义一个变量,意思就是可能该变量改变频繁,并且设计到多线程访问问题。
2、不过 现在jdk 的synchronized关键字 性能已经足够出色,也提供了多种Lock 类,因此 volatile关键字能实现的功能 jdk 的同步方法都能够实现,也是非必须的,但是内容和原理我们还是要掌握的。
volatile 修饰 有三种作用
- 可见性
对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入,意思就是 读取的一定是主内存中的最新值,
当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。
有序性
JVM 在运行class文件指令时会对代码进行一些优化,对没有依赖关系的代码执行顺序不保证是按照代码编写执行的,但能保证最后的运行结果是一样的。所以会导致在多线程环境下造成程序运行异常。如下图所示:
a、b、c、d 这4句代码 没有任何关联性,所以执行的时候 顺序不一定按图中所示执行。 意思就是 当执行到d=4 这句时 可能a 还未赋值。所以 jdk 在1.5 后优化了volatile 关键字。
如上图,定义vo 使用 volatile 修饰。这样jvm可以保证在执行 vo = 5 这句时,a、b 一定是已经赋值的,c、d 一定是未赋值的,就相当于在中间加了一个屏障,,但是volatile 并不能保证 a b 和 c d 这两句之间的执行顺序。
- 原子性
任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性。volatile 只保证自己的读写 是原子性,但是不能保证 多个对自己的指令时原子的。