AtomicInteger
两段代码
public class Sample1 { private static Integer count = 0; synchronized public static void increment() { count++; //自增 } }
public class Sample2 { private static AtomicInteger count = new AtomicInteger(0); public static void increment() { count.getAndIncrement();//自增 } }
上面两段代码都表示了+1,但是在多线程下Atomic中不需要synchronized,因为Atomic是原子性操作。而++则不行
下面我们来看AtomicInteger源码分析:
// setup to use Unsafe.compareAndSwapInt for updates private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset; static { try { valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } private volatile int value;
AtomicInteger用的是sun.misc.Unsafe调用本地方法。
value值用的是volatile修饰,volatile使多个线程共享变量,但是使用volatile使VM优化失去效果,导致效率底下,因此,AtomicInteger在合适场景下工作。
自增getAndIncrement
public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1); } public final int getAndAddInt(Object var1, long var2, int var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5; }
自减
public final int getAndDecrement() { return unsafe.getAndAddInt(this, valueOffset, -1); }
加和减
public final int getAndAdd(int delta) { return unsafe.getAndAddInt(this, valueOffset, delta); }
其实,AtomicInteger还是通过CAS去实现的
内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
CAS会带来ABA问题
解决ABA引用版本号AtomicStampedReference