薛先森* 2024-01-25 19:30 采纳率: 85.7%
浏览 4
已结题

Java变量在没有同步机制的情况下表现出了可见性



public class SyncTest {
    static class MyThread extends Thread{
        private int i;

        public MyThread(int i) {
            this.i = i;
        }

        @Override
        public void run() {
            while (res.i == this.i);
        }
    }
    private static Res res = new Res();
    public static void main(String[] args) {
        new MyThread(res.i).start();
        for (int i = 0; i < 100; i++) {
            res.i = (int) (Math.random() * 100);
        }
    }
}

为什么这里MyThread线程退出了循环,也就是res.i == this.i成立了,也就是说MyThread在没有添加同步机制的情况下获得了对res变量的可见性

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2024-01-26 04:16
    关注

    【以下回答由 GPT 生成】

    这段代码存在数据竞争的问题,根据Java内存模型(Java Memory Model),在多线程环境下,如果没有明确的同步机制(如synchronized关键字或volatile关键字),不同线程之间对共享变量的操作可能存在可见性问题。

    在本例中,主线程和MyThread线程都会对res对象的属性i进行读写操作,而没有添加同步机制。因为没有同步机制,线程对变量的修改操作会在自己的工作内存中进行,可能不及时地同步到主内存中,导致其他线程无法看到最新的值。

    然而,尽管代码中没有明确的同步机制,很多情况下仍然可以获得对res变量的可见性,这种情况下,可以说是"幸运"地获得了可见性。

    在这个具体的例子中,MyThread线程首先读取res.i的值,然后在一个循环中不断地与自己的属性i比较,直到两者相等为止。而主线程在循环中也不断地修改res.i的值。

    虽然没有明确的同步机制,但是在某些情况下,上述循环的条件res.i == this.i可能会在某一时刻成立,因为在运行时,JVM会对循环条件的右边表达式进行提前计算(lazy evaluation)。

    具体来说,在这个例子中,当MyThread线程第一次读取res.i的值时,可能会读到一个旧的值,然后在循环中一直比较旧的值与自己的属性i。但是在某个时刻,主线程可能正好在修改res.i的值时,将新的值写入主内存中。在这种情况下,MyThread线程会幸运地读取到新的值,使得循环条件成立,从而退出循环。

    然而,这种情况是不可靠的,无法保证每次运行都能成功退出循环。在不同的环境下,甚至在同一台机器上的不同时间,结果可能会不同。因此,这段代码存在着严重的竞态条件,无法保证可靠性和一致性。

    总结来说,在没有明确的同步机制的情况下,不能依赖于这种"幸运"的可见性,并且会存在数据竞争的问题。我们应该使用同步机制(如synchronized关键字或volatile关键字)来确保多线程对共享变量的正确访问。



    【相关推荐】



    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 2月3日
  • 已采纳回答 1月26日
  • 修改了问题 1月26日
  • 创建了问题 1月25日

悬赏问题

  • ¥15 单纯型python实现编译报错
  • ¥15 c++2013读写oracle
  • ¥15 c++ gmssl sm2验签demo
  • ¥15 关于模的完全剩余系(关键词-数学方法)
  • ¥15 有没有人懂这个博图程序怎么写,还要跟SFB连接,真的不会,求帮助
  • ¥15 PVE8.2.7无法成功使用a5000的vGPU,什么原因
  • ¥15 is not in the mmseg::model registry。报错,模型注册表找不到自定义模块。
  • ¥15 安装quartus II18.1时弹出此error,怎么解决?
  • ¥15 keil官网下载psn序列号在哪
  • ¥15 想用adb命令做一个通话软件,播放录音