Skip to content

violate关键字

更新: 1/11/2025 字数: 0 字 时长: 0 分钟

使用

使用方式

java
public class Vol {
    private volatile Integer num;
}

可见性

当我们的线程在使用变量时,会将它先读进自己的高速缓存区,然后使用缓存取的值。当修改完后再写回地址上

而可见性就是一个线程在修改了一个变量之后其他线程能否得知,他希望我们一个变量修改后就立刻被其他线程知道

而volatile关键字修饰变量后,他会在一个变量修改完后立刻会立即将修改后的值写入主内存,同时在读取时会从主内存中读取,而不是从线程的缓存中读取。

防重排序

我们再初始化变量时存在以下操作

  • 分配内存空间
  • 初始化对象。
  • 将内存空间的地址赋值给对应的引用。

而于操作系统可以对指令进行重排序,因此可能会先分配内存再初始化对象,而这就导致了我们多线程时可能拿到未被初始化的对象。

使用volatile修饰变量后可以保证读/写操作的重排序

常见写操作:对对象赋值(初始化对象就是这个过程)

java
Object o=new Object();

常见读操作:读取对象()

java
Object b=o; //这一步其实不只是一个读了,分为读和写两部分

volatile作了什么

由于volatile关键字修饰的变量具有可见性且wu'fa,因此volatile可以保证单次的读/写操作具有原子性。

为什么无法解决a++问题?

众所周知,a++实际上时进行了三步操作

  1. 读取i的值。
  2. 对i加1。
  3. 将i的值写回内存。

而volatile关键字只保证了1的原子性和2-3这一整体的原子性,并未保证1-2-3这一过程的原子性,因此无法解决a++问题

案例

volatile Bean

JavaBean的所有成员变量都是 volatile 类型的,并且 getter 和 setter 方法必须非常普通 —— 除了获取或设置相应的属性外,不能包含任何逻辑。

这一情况下就完美应用上了volatile的读/写原子性

基于Boolean的状态检测

状态检测时我们对Boolean变量基本就只有读写操作,所以也可以使用volatile关键字

本站访客数 人次      本站总访问量