volatile关键字使用场所

volatile关键字只能修饰变量,不能修饰类,也不能修饰方法。

想要把某个变量共享,该变量的读写操作必须是原子性的,并用volatile关键字修饰。

volatile修饰的long和double类型的变量读写操作是原子性的。long和double都是64位的,给long和double类型的变量赋值跟平台相关,在有些平台上不是原子操作。很多平台给long和double变量赋值需要2步操作,每一步只写32位,在这2个步骤之间,其他线程获取的long或double类型的变量的值的状态是不正确的。

volatile变量有类似synchronized同步代码的可见性,即每个线程读取到的都是最新更新的值。volatile的局限性很大,你只能获取volatile变量的值,直接设置volatile变量的值,不能比较之后再设置volatile的值,因为在你做比较操作的区间很有可能有其他线程修改了该volatile变量的值。

被volatile关键字修饰,表明该变量是要被多个线程访问的,编译器不会对与volatile变量相关的代码做重排或其他多线程下不允许的优化。没有被volatile关键字修饰,编译器会重排代码,缓存变量的值,减少从主存中直接获取变量的值。

用例子来详细彻底说明Java的volatile关键字工作原理

在这里插入图片描述

不用volatile关键字修饰,有可能某个线程可以获取到另一个线程设置的isActive的值,编译器有可能缓存了isActive的值等等,使用volatile关键字可以避免这些情况。

双重检查单例模式在JDK4是有问题的,volatile可以修复这个问题。本文的《第一个例子说明volatile变量的含义》中举的例子就是说这个问题。

volatile关键字的总结

  1. volatile关键字只用修饰变量,不能修饰方法和类。

  2. volatile变量的值都是从主存中获取的,而不是从线程的本地内存。

3.long和double变量被volatile关键字修饰之后,读写(赋值操作,读取操作)都是原子操作.

  1. 使用volatile关键字可以避免内存不一致的错误;写入volatile变量一定会比接下来的读操作先发生。5. 从jdk5开始对volatile变量的修改对其他的线程都是可见的;当线程读取volatile变量的时候,会先把其他线程中缓存着的volatile变量(如果还没有更新到主存中的时候)强制写入到主存。

  2. 除了long和double其他的基本类型读写操作都是原子性的;引用类型的读写操作也是原子性的。

  3. volatile变量只能做简单的读写,没有锁,没有阻塞。

8.volatile变量可以是空的.

  1. volatile不能保证原子性,比如volatile修饰的int变量++操作还是非原子的。

  2. 变量没有在多个线程之间共享,没有必要做任何同步的操作,比如使用volatile关键字修饰。

猜你喜欢

转载自blog.csdn.net/weixin_43274962/article/details/82836861