/** * Atomically increments by one the current value. * * @return the updated value */ publicfinalintincrementAndGet(){ return unsafe.getAndAddInt(this, valueOffset, 1) + 1; }
以下通过AtomitInteger的addAndGet方法来分析这一原子类是如何实现线程安全的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/** * Atomically adds the given value to the current value. * * @param delta the value to add * @param valueOffset the value memory address. * @return the updated value */ publicfinalintaddAndGet(int delta){ return unsafe.getAndAddInt(this, valueOffset, delta) + delta; }
publicfinalintgetAndAddInt(Object var1, long var2, int var4){ int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
/** * Creates a new {@code AtomicBoolean} with the given initial value. * * @param initialValue the initial value */ publicAtomicBoolean(boolean initialValue){ value = initialValue ? 1 : 0; }
/** * Atomically sets to the given value and returns the previous value. * * @param newValue the new value * @return the previous value */ publicfinalbooleangetAndSet(boolean newValue){ boolean prev; do { prev = get(); } while (!compareAndSet(prev, newValue)); return prev; }
publicfinalbooleancompareAndSet(boolean expect, boolean update){ int e = expect ? 1 : 0; //将boolean类型映射为int类型 int u = update ? 1 : 0; return unsafe.compareAndSwapInt(this, valueOffset, e, u);//通过原子操作更新当前值。 }
publicfinalintupdateAndGet(int i, IntUnaryOperator updateFunction){ long offset = checkedByteOffset(i);//得到下标在内存中的地址 int prev, next; do { prev = getRaw(offset); next = updateFunction.applyAsInt(prev);//转为int } while (!compareAndSetRaw(offset, prev, next)); return next; }
publicclassAtomicReferenceTest{ publicstaticvoidmain(String[] args){ AtomicReference<User> atomicReference = new AtomicReference<User>(); User firstUser = new User("long", 23); atomicReference.set(firstUser); User secondUser = new User("kai", 24); atomicReference.compareAndSet(firstUser, secondUser); System.out.println(atomicReference.get().getName()); System.out.println(atomicReference.get().getAge());