前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入理解CAS

深入理解CAS

作者头像
鳄鱼儿
发布2024-05-21 16:26:36
440
发布2024-05-21 16:26:36
举报

深入理解CAS (Compare and swap )

CAS:比较当前工作内存中的值和主内存中的值,如果这个值是期望的,就执行操作,否则就一直循环。

举例对比

不使用CAS,多线程环境不使用原子类保证线程安全i++(基本数据类型),加同步锁 synchronized

代码语言:javascript
复制
public class T1 {
    volatile int number=0;
    //读取
    public int getNumber(){
        return number;
    }
    //写入加锁保证原子性
    public synchronized  void setNumber(){
        number++;
    }
}

使用CAS,在多线程环境利用原子类 AtomicInteger 保证线程安全i++(基本数据类型),类似乐观锁

代码语言:javascript
复制
import java.util.concurrent.atomic.AtomicInteger;
 
public class T1 {
    AtomicInteger atomicInteger=new AtomicInteger();
    //读取
    public int getAtomicInteger(){
        return atomicInteger.get();
    }
    //写入原子整型类保证原子性
    public void setAtomicInteger(){
        atomicInteger.incrementAndGet();
    }
}

缺点

ABA

问题描述:线程t1将它的值从A变为B,再从B变为A。同时有线程t2要将值从A变为C。但CAS检查的时候会发现没有改变,但是实质上它已经发生了改变 。可能会造成数据的缺失。

解决方法:CAS还是类似于乐观锁,同数据乐观锁的方式给它加一个版本号或者时间戳,如AtomicStampedReference。

自旋消耗资源

问题描述:多个线程争夺同一个资源时,如果自旋一直不成功,将会一直占用CPU。

解决方法:破坏掉while死循环,当超过一定时间或者一定次数时,return退出。JDK8新增的LongAddr和ConcurrentHashMap类似的方法。当多个线程竞争时,将粒度变小,将一个变量拆分为多个变量,达到多个线程访问多个资源的效果,最后再调用sum把它合起来。虽然base和cells都是volatile修饰的,但感觉这个sum操作没有加锁,可能sum的结果不是那么精确。

多变量共享一致性问题

解决方法: CAS操作是针对一个变量的,如果对多个变量操作,

  1. 可以加锁来解决。
  2. 封装成对象类解决。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 深入理解CAS (Compare and swap )
    • 举例对比
      • 缺点
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档