volatile的不保证原子性的证明

volatile的不保证原子性的证明

class MyData{
    volatile int number;
    public void increaseOne(){
        this.number++;
    }
}
public class Test {
    public static void main(String[] args) {
        MyData data = new MyData();
        for (int i = 0; i < 100; i++) {
            for (int j = 0; j < 100; j++) {
                new Thread(()->{
                    data.increaseOne();
                },String.valueOf(i)).start();
            }
        }
        //当其他线程执行完毕之后,再打印number的值
        //java默认的后台线程为main线程和线程,所以当activeCount>2的时候,说明还有其他的线程没有执行完毕
        while (Thread.activeCount() > 2){
            Thread.yield();
        }

        System.out.println(data.number);
    }
 }

控制台输出结果:
9996
//如果保证原子性,输出结果应该为100*100=10000

分析

class MyData{
    volatile int number;
    public void increaseOne(){
        this.number++;
    }
}

increaseOne的字节码指令

 public void increaseOne();
    Code:
       0: aload_0                          //从局部变量0中装载引用类型值
       1: dup                               //复制栈顶部一个字长内容
       2: getfield      #2                  // Field number:I    从对象中获取字段
       5: iconst_1
       6: iadd                                //进行加1操作
       7: putfield      #2                  // Field number:I   设置对象中字段的值
      10: return

线程A执行完iadd后还没来得及执行putfield,CPU调度时间片给线程B执行加一操作,而线程B加的数据还是原始的值,而不是A进行加一操作后的值,所以发生了写覆盖

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值