16:27 2023-01-20 15:34 采纳率: 0%
浏览 22

java线程可见性问题

java多线程可见性问题
flag先true后false导致不可见性,而且加sout和sleep会恢复,先false后true也不会发生可见性问题
public class VisibilityDemo01 {
public static void main(String[] args) {
    MyThread01 t = new MyThread01();
    t.start();
    while (true){
        if (t.isFlag()){
            System.out.println("entry");
        }
    }                         //flag先truefalse导致不可见性,而且加sout和sleep会恢复
                                //先falsetrue不会
}

}

class MyThread01 extends Thread {
public boolean flag = false;

public void run() {
    try {
        sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    flag = true;
    System.out.println(flag);
}

public boolean isFlag() {
    return flag;
}

}
//这个不会发生可见性问题

flag先false后true运行正常
刚开始我以为不会读取最新值,但现在这个结果又会读取最新值
为什么会出现flag先true后false导致不可见性,而且加sout和sleep会恢复,先false后true也不会发生可见性问题
  • 写回答

2条回答 默认 最新

  • 「已注销」 2023-01-20 16:29
    关注

    这是因为在Java中,多线程之间的变量共享需要遵循一些规则来确保可见性。当一个线程修改变量时,其它线程可能并不能立即看到这个修改。在第一种情况中,主线程在子线程执行完之前就读取了变量的值,而子线程修改了变量之后主线程并不能立即看到这个修改,因此导致了不可见性问题。在第二种情况中,子线程在主线程读取变量之前就已经修改了变量,因此主线程能够看到这个修改。

    在第一种情况中,加入sout和sleep的作用是在修改变量之后让主线程有时间读取到修改后的值,因此可见性问题得到了解决。

    具体来说,解决方法有:

    • 使用volatile关键字修饰变量,这个关键字可以禁止指令重排和缓存,保证可见性.

    • 使用synchronized关键字修饰变量或方法,这个关键字可以禁止多线程并发访问,保证可见性.

    • 使用Lock锁,这个锁可以禁止多线程并发访问,保证可见性.

    • 使用Atomic类,这个类提供了CAS算法,保证可见性.

    评论

报告相同问题?

问题事件

  • 创建了问题 1月20日

悬赏问题

  • ¥30 STM32 INMP441无法读取数据
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境