volatile

文章目录

volatile

可见性

问题:t 线程会从自己的高速缓存中读取run值,而无法获取到更新后的值,导致程序无法结束。

java 复制代码
@Slf4j
public class Test05 {
    static boolean run = true;
    public static void main(String[] args) {
        new Thread(() ->{
            int i=0;
            while(run){
                i++;
            }
        }).start();
        log.info("开始任务");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        run = false;
        log.info("停止任务");
    }
}

解决方法:给run加上volatile(易变的)属性,避免从工作缓存中读取值,而必须到主缓存中获取值,保证数据在不同线程中的可见性。

java 复制代码
static volatile boolean run = true;

指令重排

问题:r1的结果可能为0,因为actor2中的两行代码可能会发生指令重排,导致执行顺序颠倒。

java 复制代码
int num = 0;
boolean ready = false; 
// 线程1 执行此方法 
public void actor1(I_Result r) {
    if(ready) { 
        r.r1 = num + num;
    }else {
        r.r1 = 1;
    } 
}
// 线程2 执行此方法 
public void actor2(I_Result r) {
    num = 2;
    ready = true;
}

解决:给ready添加volatile关键字

java 复制代码
volatile boolean ready = false;

volatile原理

volatile的底层实现原理是内存屏障,Memory Barrier(Memory Fence)

  • 对 volatile 变量的写指令后会加入写屏障
  • 对 volatile 变量的读指令前会加入读屏障

而有了屏障之后,可见性和有序性就有了很好的解决。

可见性:

  • 写屏障(sfence)保证在该屏障之前的,对共享变量的改动,都同步到主存当中
  • 读屏障(lfence)保证在该屏障之后,对共享变量的读取,加载的是主存中新数据

有序性:

  • 写屏障会确保指令重排序时,不会将写屏障之前的代码排在写屏障之后
  • 读屏障会确保指令重排序时,不会将读屏障之后的代码排在读屏障之前

虽然volatile可以保证可见性和有序性,但它并不能保证复合操作(如自增、自减或检查后执行逻辑)的原子性。因此,volatile并不能替代同步机制(如synchronized)来控制对共享资源的并发访问。

相关推荐
悟能不能悟3 分钟前
java HttpServletRequest 设置header
java·开发语言
云栖梦泽8 分钟前
易语言运维自动化:中小微企业的「数字化运维瑞士军刀」
开发语言
悟空码字10 分钟前
SpringBoot整合FFmpeg,打造你的专属视频处理工厂
java·spring boot·后端
刘975311 分钟前
【第23天】23c#今日小结
开发语言·c#
独自归家的兔12 分钟前
Spring Boot 版本怎么选?2/3/4 深度对比 + 迁移避坑指南(含 Java 8→21 适配要点)
java·spring boot·后端
郝学胜-神的一滴21 分钟前
线程同步:并行世界的秩序守护者
java·linux·开发语言·c++·程序人生
superman超哥22 分钟前
Rust 移动语义(Move Semantics)的工作原理:零成本所有权转移的深度解析
开发语言·后端·rust·工作原理·深度解析·rust移动语义·move semantics
青茶36023 分钟前
【js教程】如何用jq的js方法获取url链接上的参数值?
开发语言·前端·javascript
superman超哥33 分钟前
Rust 所有权转移在函数调用中的表现:编译期保证的零成本抽象
开发语言·后端·rust·函数调用·零成本抽象·rust所有权转移