JDK学习笔记之AtomicInteger

AtomicInteger 可以算是一类Automic类的代表,在多线程的运行环境中,提供原子操作。

AtomicInteger 的 Java doc

AutomicInteger 可以让多线程程序更新一个int 值,但是保证更新的原子性,普通的Integer 更新的时候分为3步:

  1. 读取int值
  2. 计算更新后的int值
  3. 将更新后的int值写回到内存中

由于这3步不是一个原子操作,所以多线程的更新的时候,就会出现线程a读取的值为1,并且根据1计算,但是在真正写入之前,这个值已经被b写成了别的值,这就会导致程序的错乱。这也就是为什么我们要用AutomicInteger的原因。

使用实例:
AtomicInteger ai = new AtomicInteger(0);
ai.addAndGet(5); // 5
ai.getAndAdd(1); // 5
ai.get(); // 6

原理

AtomicInteger内有一个Unsafe类,支持CAS操作,而且类内部还有一个value类(使用volatile保证内存更新可见性)记录对象值。

CAS是Compare And Swap 的缩写,也就是在更新前会比较目标对象的值是不是所期望的值,也就是一次更新需要2个值,期望的原来的值和要更新成的值。

例如: 将变量a 从1更新为2

Unsafe 是通过调用C++代码调用CPU指令达到原子性的操作,具体内部实现参看下面代码实例(给一个atomicInterger加一个值):

    // var2 是变量内存地址, var4为要增加的值
    public final int getAndAddInt(Object var1, long var2, int var4) {  
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);  // var5 拿到当前值
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    } 

通过上面代码可以看出,如果没有更新成功,这个循环会一直进行。

ABA问题

上述的AtomicInteger原理虽然可以解决多线程并发的问题,但是并不完美,会有ABA的问题出现。
具体见 ABA

ABA的问题本质是因为CAS的方式是用乐观锁实现,不会锁住共享变量,是一种非阻塞的同步机制。
但是却没有大多数乐观锁的唯一递增version字段来保证更新的顺序,所以会出现ABA问题。

你可能感兴趣的:(JDK学习笔记之AtomicInteger)