并发编程5.CAS

什么是CAS

compare and swap

CAS的方式对属性private int value = 0; 进行递增操作

  1. 读取 value 的值
  2. 将其赋值给临时变量 a,此时 a = 0;
  3. a中获取值进行计算,将所得结果赋值给变量b,此时 a = 0; b =1;
  4. 重新读取value的值,与a进行比较
  5. 如果两个值相等,则将b中的值写入到value
  6. 如果不相等,则从头开始读取value的,赋值给a,计算,再进行读取比较,直到赋值成功为止!
比较相等
比较不相等
读取 value 的值
将值赋值给 a
进行结算将结果赋值给 b
读取 value 的值与 b的值进行比较
将b的值写入到 value

源码

AtomicInteger 为例,追溯其incrementAndGet 的逻辑

AtomicInteger counter = new AtomicInteger();
counter.incrementAndGet();

incrementAndGet 方法中

public final int incrementAndGet() {
    return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}

incrementAndGet 方法先increment 然后 get
调用了sun.misc.Unsafe类的 getAndAddInt 方法,而里面调用的是 getAndAddInt ,是先get然后再add,所以这里需要加1

getAndAddInt

public final int getAndAddInt(Object o, long offset, int delta) {
    int v;
    do {
        v = getIntVolatile(o, offset);
    } while (!compareAndSwapInt(o, offset, v, v + delta));
    return v;
}

调用 compareAndSwapInt 方法,而此方法是一个native方法,因此我们需要从hotspot源码src/share/vm/prims/unsafe.cpp 中的实现

UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
  UnsafeWrapper("Unsafe_CompareAndSwapInt");
  oop p = JNIHandles::resolve(obj);
  jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
  return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END

这里调用了Atomiccmpxchg 方法,在src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp

inline jint     Atomic::cmpxchg    (jint     exchange_value, volatile jint*     dest, jint     compare_value) {
  int mp = os::is_MP();
  __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
                    : "=a" (exchange_value)
                    : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
                    : "cc", "memory");
  return exchange_value;
}

这里调用了汇编中的cmpxchgl 指令

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心扬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值