Volatile的可见性问题小坑

本文通过实验探讨了多线程环境下未使用Volatile关键字时,变量更新的可见性问题。作者发现,即使不使用Volatile,主线程修改变量后,子线程也能感知到变化,但移除System.out.println后,子线程则陷入无限循环,证实了多线程中变量副本的存在。
摘要由CSDN通过智能技术生成

自己写了一个程序,来测试如果在多线程中没有使用Volatile,在外部修改这个变量之后会发生什么。
很遗憾的是,并没有像网上说的那样——程序会无限循环。

public class VolatileTest {
    static int flag = 0;
    public static void main(String[] args) throws InterruptedException {
        new Thread() {
            @Override
            public void run() {
                while (flag == 0) {
                    System.out.println("我在循环啊啊啊");
                }
                System.out.println("知道了修改了flag");
            }
        }.start();
        Thread.sleep(500);
        flag = 60;
        System.out.println("已经修改了flag");
    }

}

正常情况来说,因为线程会有一个flag的副本。
在main中修改flag=60之后,之前的线程应该还是保存着旧的副本。
线程中的变量flag=0才对。应该永远不会输出“知道了修改了flag”。但是事实恰恰相反。很奇怪。难道多线程不存在副本吗?

在这里插入图片描述
从网上得知↓↓↓ 其实线程很可能自动刷新了本地内存

System.out.println();方法有 synchronized 修饰。
使得虚拟机很有可能刷新本地内存。然后有些错误的并发代码加了行输出做调试就看起来正常了……
在这里插入图片描述

所以我将循环体内的 System.out.println方法去掉。

public class VolatileTest {
    static int flag = 0;
    public static void main(String[] args) throws InterruptedException {
        new Thread() {
            @Override
            public void run() {
                while (flag == 0) {

                }
                System.out.println("知道了修改了flag");
            }
        }.start();
        Thread.sleep(500);
        flag = 60;
        System.out.println("已经修改了flag");
    }

}

结果成功了。
程序一直在while(flag==0)跳不出来。高兴!证明多线程是存在变量副本的。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值