当前位置: 首页 > article >正文

volatile

文章目录

  • volatile
    • 可见性
    • 指令重排
    • volatile原理

volatile

可见性

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

@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(易变的)属性,避免从工作缓存中读取值,而必须到主缓存中获取值,保证数据在不同线程中的可见性。

static volatile boolean run = true;

指令重排

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

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关键字

volatile boolean ready = false;

volatile原理

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

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

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

可见性:

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

有序性:

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

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


http://www.kler.cn/a/291964.html

相关文章:

  • AWTK-WIDGET-WEB-VIEW 实现笔记 (4) - Ubuntu
  • Vue3 provide 和 inject的使用
  • day-83 最少翻转次数使二进制矩阵回文 II
  • 一个win32 / WTL下多线程库(CThread类)的使用心得
  • 电脑长期不用,开不了机怎样解决
  • 【miniMax开放平台-注册安全分析报告-无验证方式导致安全隐患】
  • 嵌入式OpenHarmony系统的一些特点
  • web笔记:JSP基础
  • 添加配置react组件路由具体步骤参考
  • 利用SSH加密实现的HTTP隧道分析与检测
  • 编译 ffmpeg 以支持AVS格式视频解码与解码
  • Chapter 06 axios使用指南
  • 【gtokentool】什么是数字货币?怎么使用?
  • 设计模式 代理模式(Proxy Pattern)
  • fast-voice-assistant
  • C++ 在变量前面加上(void)的作用
  • Jsoncpp的安装与使用
  • 【免越狱】iOS任意版本号APP下载
  • Apache Spark简介
  • 振动分析-26-频域分析之深入理解功率谱和功率谱密度的计算过程
  • 全国大学生数学建模竞赛全国奖项评阅工作规范(2023年修订稿)
  • 干货分享|分享一款免费开源的动态壁纸软件 Lively Wallpaper
  • LeetCode491 非递减子序列
  • Docker部署项目时的服务端口设置——给容器添加新端口映射
  • Android Studio gradle下载太慢了!怎么办?(已解决)
  • Leetcode每日刷题之155.最小栈