CAS和原子类

CAS

一种在操作系统层实现的并发算法。Java中的原子包大量使用了该算法来简化多线程编程。
当前内存值V 预期原值A 预期目标值B。当V==A时,将B赋值给变量,返回true,否则什么都不做,返false。

在Java中,通过UnSafe类对操作系统底层的CAS进行封装。以AtomicInteger为例子,对源码实现进行分析;

public class AtomicInteger extends Number implements java.io.Serializable {
    private static final long serialVersionUID = 6214790243416807050L;

    // setup to use Unsafe.compareAndSwapInt for updates 使用UnSafe类来调用compareAndSwapInt方法,对变量进行原子更新操作。
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    // 变量内存偏移地址  UnSafe通过内存偏移地址来获取变量的值。 
    private static final long valueOffset;

    static {
      try {
      // 初始化时获取变量内存偏移地址 
        valueOffset = unsafe.objectFieldOffset
            (AtomicInteger.class.getDeclaredField("value"));
      } catch (Exception ex) { throw new Error(ex); }
    }
	// 变量的值 volatile修饰 保证看到的总是最新值 即多线程可见性
    private volatile int value;

// 对addAndGet方法进行分析  入参为增量 
 public final int addAndGet(int delta) {
 // 自旋操作 直到成功
        for (;;) {
        // 获取原值 value
            int current = get();
            // 预期目标值=原值+增量
            int next = current + delta;
            // 原子操作 将预期原值 和预期目标值传入
            if (compareAndSet(current, next))
                return next;
        }
    }
public final boolean compareAndSet(int expect, int update) {
// UnSafe类参数为 变量引用  内存偏移量 预期原值 预期目标值  该方法为native方法  实现为:通过内存偏移量获取内存中的值和预期原值比较,两者相等则将内存值设为预期目标值并返回true,否则什么都不做,返回false
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
ABA问题

两个线程X Y Z同时对一个原子AtomicInteger 进行操作,原值为A。线程X Z读取到最新值均为A,线程X先将值改为B成功。然后线程Y读取到最新值为B,又将值改为A,线程Z在进行CAS操作时,感知不到线程X进行过修改,这就是ABA问题。
场景分析,一个单项链表实现的栈,原本

针对ABA问题,提供了AtomicStampedReference原子引用类,通过控制变量版本号保证CAS的正确性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值