CAS原子操作

本文介绍了比较并交换(CAS)机制的基本原理及其在Java并发编程中的应用。详细解释了AtomicInteger类如何利用CAS进行线程安全的操作,并展示了如何使用AtomicStampedReference解决CAS的ABA问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CAS

翻译成中文为比较并交换,是对cpu的层面而言,在java中主要是通过java.util.concurrent.atomic包下的一些原子操作类实现的
在这里插入图片描述

这些类的实现是通过unsafe类实现,而unsafe类执行的是native方法,底层是由c++写的

public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
public class MyTest {
   public static void main(String[] args) {
      AtomicInteger atomicInteger = new AtomicInteger(1);
      //1改为2
      System.out.println(atomicInteger.compareAndSet(1, 2));
      System.out.println(atomicInteger.get());
      //2改为3
      System.out.println(atomicInteger.compareAndSet(2, 3));
      System.out.println(atomicInteger.get());
      //2改为4
      System.out.println(atomicInteger.compareAndSet(2, 4));
      System.out.println(atomicInteger.get());
   }
}
//执行结果
true
2
true
3
false
3

但是普通的cas是有ABA的问题的,也就是如果A和B同时拿到变量的值为1,B线程将i变量改成了2,在改成了1.这是A线程修改值的时候,发现拿到的值为1,与内存中的值相等,所以他也将值修改了,但是原则上这个是不准修改的

AtomicReference和AtomicStampedReference都是对于对象的引用,与AtomicInteger是非常相似的,只不过AtomicInteger是对整数的封装,AtomicStampedReference较于AtomicReference,内部添加了时间戳的验证,在compareAndSet时,不仅要比较期望值,还要比较一个时间戳,其实就相当于版本号,每一次compareAndSet就修改对应的时间戳(往上加),相当于compareAndSet时做了双重检测,就完美的解决了ABA问题

public class MyTest {
   public static void main(String[] args) {
      AtomicStampedReference<String> stringAtomicStampedReference = new AtomicStampedReference<String>("A",1);
      //将A改为B
      System.out.println(stringAtomicStampedReference.compareAndSet("A", "B", 1, 2));
      System.out.println(stringAtomicStampedReference.getReference());
      System.out.println(stringAtomicStampedReference.getStamp());
     //将B改为A
      System.out.println(stringAtomicStampedReference.compareAndSet("B", "A", 2, 3));
      System.out.println(stringAtomicStampedReference.getReference());
      System.out.println(stringAtomicStampedReference.getStamp());
       
      //将A改为B
      System.out.println(stringAtomicStampedReference.compareAndSet("A", "B", 1, 2));
      System.out.println(stringAtomicStampedReference.getReference());
      System.out.println(stringAtomicStampedReference.getStamp());
   }
}
//执行结果
true
B
2
true
A
3
false
A
3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值