很诡异的一件事情

下面这段代码是验证static的线程可见性的

public class TestStatic {

    public static void main(String[] args) {
        Data data = new Data();
        new Thread(() -> {
            System.out.println("线程启动a值为:"+data.a);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            data.change();
            System.out.println("线程结束a值为:"+data.a);
        }).start();
        //如果读取不到最新a值这里会死循环
        while (data.a==0){
//            System.out.println("死循环");  //当这段代码注释掉后,很开心的可以验证,没有使用volatile确实线程不可见,但是当把这个注释解开之后神奇的事情发生了,竟然走出死循环了!!!百思不得其解
        }
        System.out.println("a的值改变,并且被主线程看到");
    }

}

class Data{
    int a = 0;
    void change(){
        a = 4;
    }
}

 

再看下一张图

 

 why???为甚??

查看其字节码

相比这两张图仅仅多了一行getstatic指令,竟然能使结果截然不同,为什么呢????

继续测试

public class TestStatic {

    public static void main(String[] args) {
        Data data = new Data();
        new Thread(() -> {
            System.out.println("线程启动a值为:"+data.a);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            data.change();
            System.out.println("线程结束a值为:"+data.a);
        }).start();
        //如果读取不到最新a值这里会死循环
        while (data.a==0){
            
            int b = 4;//添加这行代码,结果也是处于死循环中,不能正常结束
//            System.out.println("死循环");
        }
        System.out.println("a的值改变,并且被主线程看到");
    }

}

class Data{
     int  a = 0;
    void change(){
        a = 4;
    }
}

=============================================

public class TestStatic {

    public static void main(String[] args) {
        Data data = new Data();
        new Thread(() -> {
            System.out.println("线程启动a值为:"+data.a);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            data.change();
            System.out.println("线程结束a值为:"+data.a);
        }).start();
        //如果读取不到最新a值这里会死循环
        while (data.a==0){
            
            Arrays.asList();//添加这行代码后,竟然能正常结束了,查看字节码指令,也多出来个getstatic指令,由此可以推断出,一定是这个getstatic指令的问题,但是为什么呢?不知道,还要继续研究
//            System.out.println("死循环");
        }
        System.out.println("a的值改变,并且被主线程看到");
    }

}

class Data{
     int  a = 0;
    void change(){
        a = 4;
    }
}

结论:

只要在while循环中调用static方法,就会出现getstatic指令,就能够正常结束,但是我没有用volatile关键字啊,为什么能正常结束呢???应该处于死循环状态啊

有知道的吗??

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值