Thread.Sleep是否会对影响内存可见性

昨天群友提了一个问题代码如下:

public class mytest {

    Integer a = 0;
    public static void main(String[] args) throws InterruptedException {
        mytest test = new mytest();
        test.testVisibility();
    }


    public void testVisibility() {
        new Thread(() -> {
            System.out.println("thread 1 start ======= a =" + this.a);
            while (this.a != 10) {
            }
            System.out.println("thred 1 a =======" + this.a);
            System.out.println("thread 1 end =======");
        }).start();

        try {
            Thread.sleep(1000);
            // TimeUnit.NANOSECONDS.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            System.out.println("thread 2 modify ....");
            this.a = 10;
            System.out.println("thread 2 modify success a = " + this.a);
        }).start();

    }

}

根据我认知的内存可见性,中间的睡眠是为了保证线程能先启动并先进入while循环,线程二随后启动修改a的值,线程一先拿到a的副本放到本地工作内存中,并没有去主存中刷新a的值一直是0,而线程二修改a的值为10之后刷新到主存中,线程一看不到所以程序不会暂停。
我第二次把中间的sleep注释掉,那么线程一就能顺利的结束,我又多次调整睡眠的时间大小(我本机windows10 大于1个毫秒就无法正常结束,群友测试1纳秒的时候会时好时坏)的情况。
最终大概得出一个可以接受的结论:
进入while循环后,并不是说就不刷新主存了,cpu偶尔也会去刷新一下主存,这样的等待时间对我们来说是非常短暂的,但对于高速的cpu来说是漫长的,如果线程一进入while,不停的再去主存中刷新a的值,他的值一直都是0,那么如果超过一定次数或者时间cpu会不会对这种情况进行优化呢?我猜是有可能的。所以才会出现这种情况。
顺便还有一点如果在线程一种 while中调用同步方法的时候,共享变量也是会主动去主存中刷新的。所以线程一种如果while中加入了print()方法,那么程序就能正常结束了。
特此记录一下。
结论影响内存可见性的是
Thread.sleep ,println 都会影响到 《《当前》》 线程 将副本与主存同步

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值