验证volatile可见性之诡异事件

纸上得来终觉浅,绝知此事要躬行

今天在学习volatile可见性的时候看见一个案例,于是进行编码验证,结果出现了诡异的事件,new了一个线程是改变变量,结果却对主线程可见了,居然跳出了循环。
下面贴出代码

class Test01 {
    int num = 0;

    public void numTo60() {
        this.num = 60;
    }

}

public class Test {

    public static void main(String[] args) {
        Test01 test01 = new Test01();
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t commit on");
            try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
            test01.numTo60();
            System.out.println("update num to 60 " + test01.num);
        }, "AAA").start();

        while (test01.num == 0) {
        }
        System.out.println(Thread.currentThread().getName()+"_get num value to " + "\t" + test01.num);
    }
}

测试结果如下

AAA	 commit on
update num to 60 60
main_get num value to 	60

结果非常诡异,明明变量没有加volatile关键字,子线程的修改居然对main线程可见,非常奇怪,于是百度查询,已经问身边的朋友。得到的结果是System.out.println是加synchronized导致的,关于synchronized关键字是是这样解释的

1、获得同步锁;
2、清空工作内存;
3、从主内存拷贝对象副本到工作内存;
4、执行代码(计算或者输出等)5、刷新主内存数据;
6、释放同步锁。

看到这里大家是否觉得这就是答案了?,但是结果却不是,本人将printLn换成log.info输出也不行,后来干脆什么都不打印。得到的结果依然是跳出循环,
在这里插入图片描述
结果还是比较出人意料的。目前楼主还没找到问题的原因,等以后发现问题,会及时更新上出现这个问题的根本原因,所以学习一样东西还是得动手实践才行,网上博客千篇一律,你抄我,我抄你,从理论上来将结果就是阻塞住,但是结果却不是,难道是最新的jvm虚拟机做了优化?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值