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

 

 

 

posted @ 2017-04-11 22:18  孤独时光  阅读(172)  评论(0编辑  收藏  举报