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++实际上时进行了三步操作
- 读取i的值。
- 对i加1。
- 将i的值写回内存。
而volatile关键字只保证了1的原子性和2-3这一整体的原子性,并未保证1-2-3这一过程的原子性,因此无法解决a++问题
案例
volatile Bean
JavaBean的所有成员变量都是 volatile 类型的,并且 getter 和 setter 方法必须非常普通 —— 除了获取或设置相应的属性外,不能包含任何逻辑。
这一情况下就完美应用上了volatile的读/写原子性
基于Boolean的状态检测
状态检测时我们对Boolean变量基本就只有读写操作,所以也可以使用volatile关键字