通过10个线程对数字分别进行1000次自增来理解CAS+volatile 和synchronized的区别

首先看个代码:`

class Resource{
   int num=0;
    public  void  add(){
        num++;
    }
}
public class Main2<fori> {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(10);
        Resource resource = new Resource();
        for (int i=0;i<10;i++){
            new Thread(()->{
                for (int j=0;j<1000;j++){
                    resource.add();
                }
                countDownLatch.countDown();
            }).start();
        }

        countDownLatch.await();
        System.out.println(resource.num);
    }

}

运行结果是9718而不是预想的10000
在这里插入图片描述
面对这样的情况有两种解决办法:
1.加重锁:synchronized :只能有一个线程对num进行读写
2.CAS+volatile:允许多个线程同时操作,CAS原理就是比较内存值和期望值是否一样,如果一样则更新,不一样则进行自旋,这里用volatile来保证重新从主内存中取到的值是最新值

①没有加volitail的变量i :写覆盖 :两个线程同时读取到内存中的值时,会将重复的值写入内存两次(写的时候并非是同一时刻)
②加了volitail的变量i:  写无效  :两个线程同时读取到内存中的值时 ,两个线程看谁先将值写的内存当中去,如果第一个线程将值写到了内存当中,那么另一个线程加之后的值作废,即当次循环作废
③原子类:  两个线程同时读取到内存中的值时 ,第一个线程修改了值以后,另一个线程不会写无效,而是将内存中的值取出来作为下次cas期望的值,重新cas,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值