CAS-AtomicIntger 为例

2019-04-29  本文已影响0人  Wi1ls努力努力再努力

众所周知,i++或者++i 是线程不安全的,因为其涉及到读取,自增,赋值等多步操作而非原子操作。
Java 提供了 AtomicInteger ,利用 CAS 进行原子性的自增。

@AtomicInteger
private volatile int value;

public final int incrementAndGet( ){
  for(;;){
    int current = get( );
    int next = current + 1;
    if(compareAndSet(current, next){
        return next;
    }
  }
}

public final int get( ){
  return value;
}

AtomicInteger 自增的原子性是通过 CAS的死循环进行的,即一种乐观锁。


多线程进行++i 的时候,会导致覆盖导致自增失败。
value 是 volatile,因为是线程可见的。而 其自增的可靠性在于强调的是自增的次数。如果本次自增失败,那么下次循环继续尝试直到成功为止。

Unsafe.compareAndSwapInt( )最后是在汇编层面加了锁,直接操作了内存

@atomic_linux_x86.inline.hpp
#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: "

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;
}
上一篇 下一篇

猜你喜欢

热点阅读