梦想总是要不可及,是不是应该放弃 2020-12-23 15:35 采纳率: 0%
浏览 172

为什么没有synchronized或volatile也能保证共享变量的可见性

为了验证synchronized的可见性,编写一下代码:

共享变量的Marker类:

class Marker{
    public boolean b;
    public Marker(boolean b){
        this.b = b;
    }
}

线程类:

public class MyThread implements  Runnable{

    Marker marker;

    public MyThread(Marker marker){
        this.marker = marker;
    }

    public void run() {
        try{
            Thread.sleep(100);
        }catch (Exception e){
            System.out.println(e.toString());
        }
        this.marker.b = false;
    }
}

主类:

public class synchronizedTest {

    public static void main(String[] args) {

        Marker marker = new Marker(true);

        new Thread(new MyThread(marker)).start();

        while(marker.b){
            System.out.println("ok");
        }
    }
}

执行后的结果是:

ok
ok
......
ok


Process finished with exit code 0

多次执行,还是可以得到这个结果,可见,我没有复现出“不可见”的问题。子线程对共享变量marker对象的修改,对于主线程来说是可见的。为什么会这样呢?

  • 写回答

6条回答 默认 最新

  • 关注

    原因找到了,因为main()方法中第10行,System.out.println("ok");,这里面有个println方法,是自带synchronized,是会将主内存中的数据强制刷新到工作内存中,因此主线程可以发现子线程对marker的修改。只要删掉第10行,就会存在可见性问题。

    评论

报告相同问题?

悬赏问题

  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题
  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入