violate原理
violate能够保证变量的可见性和有序性 可见性:我们对一个共享变量的读取和写入可能不会立即刷新到内存,可能处于缓存,这个时候读取或者写入可能不是最新的值,可见性保证读取的是最新的值,写入操作立即刷新到内存 有序性:jvm为了优化执行效率,代码的执行顺序不一定会按照我们编写的顺序执行,多线程环境下可能会产生线程安全问题 violate保证可见性和有序性的原理是通过内存屏障实现的
- violate修饰的变量会在写入操作之后加入写屏障
- violate修饰的变量会在读操作之前加入读屏障
1. 保证可见性
- 写屏障保证在写屏障之前的写入操作对共享变量的改动都同步到主存当中
public void actor2(I_Result r) { num = 2; ready = true; // ready 是 volatile 赋值带写屏障 // 写屏障 } - 读屏障保证在读屏障之后对于共享变量的读取都是读取的内存中最新的数据
public void actor1(I_Result r) { // 读屏障 // ready 是 volatile 读取值带读屏障 if(ready) { r.r1 = num + num; } else { r.r1 = 1; } }2. 保证有序性
- 写屏障保证在指令重排序时,不会将写屏障之前的代码重排在写屏障之后
public void actor2(I_Result r) { num = 2; ready = true; // ready 是 volatile 赋值带写屏障 // 写屏障 } - 读屏障保证在指令重排序时,,不会将读屏障之后的代码排在读屏障之前
public void actor1(I_Result r) { // 读屏障 // ready 是 volatile 读取值带读屏障 if(ready) { r.r1 = num + num; } else { r.r1 = 1; } }