众所周知,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;
}
网友评论