debug模式下所有变量有volatile的效果?

java中非volatile变量读取是从工作内存中读取,不一定可以读到主内存的最新数据。volatile变量保证每次读取都要从主内存中拿。

 

写了一段代码来验证这一点

 

public class MemoryMode {

    private volatile boolean flag = false;//这个类型是volatile的时候,结果是conditionChanged:true

    public void setFlag(){
        flag = true;
    }

    private  boolean conditionChanged = false;

    public static class LoopRunnable implements Runnable{
        private MemoryMode memoryMode;
        public LoopRunnable(MemoryMode memoryMode){
            this.memoryMode = memoryMode;
        }
        public void run() {
            while (true){//标记未改变,一直循环
                if(memoryMode.flag){
                    memoryMode.conditionChanged = true;
                    break;
                }
            }

        }
    }

    public static class SetFlagRunnable implements Runnable{
        private MemoryMode memoryMode;
        public SetFlagRunnable(MemoryMode memoryMode){
            this.memoryMode = memoryMode;
        }
        public void run() {
            memoryMode.setFlag();//改变标记值
        }
    }
    public static void main(String[] args) throws InterruptedException {
        MemoryMode memoryMode = new MemoryMode();

        LoopRunnable loopRunnable = new LoopRunnable(memoryMode);
        Thread a = new Thread(loopRunnable);
        Thread b = new Thread(new SetFlagRunnable(memoryMode));

        a.start();
        Thread.sleep(10000);
        b.start();

        a.join();
        b.join();

        System.out.print("conditionChanged:"+memoryMode.conditionChanged);
    }
}

 

 

上面这段代码申明了一个volatile修饰的名称为flag的变量,初始值为false。启动一个线程a,run方法是一个死循环,flag为true时才退出循环。然后启动另外一个线程b,改变flag的值到true。因为flag一个volatile变量,值被线程b改变后,对线程a是立即可见的,所以可以代码可以正常退出。

 

把上面的代码修改一下,去掉flag对象的volatile修饰。期待a线程一直读不到flag的值变为true,代码一直循环,不能正常退出。

 

在Intellij里,选择run as application,和期望的一样,代码确实不能正常退出。但是,如果选择的是debug as application的话,代码可以正常退出的,和标记为volatile的效果一样。

 

可以猜想,debug模式下,所有变量都是从主内存中读取的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值