AtomicInteger源码分析

前言

  AtomicInteger使得在高并发的场景下,可以安全的操作整数的增减。主要原理是采用Unsafe.CAS操作。

原子操作类

  多线程同时对int i进行操作,可能导致原子性问题。
  可以加Synchronized悲观锁解决,考虑到性能问题,JDK1.5后,J.U.C包提供Atomic包 → 对常用数据结构做原子操作。
  J.U.C中的原子操作类有:

  • 原子基本类型
    • AtomicBoolean、 AtomicInteger、 AtomicLong
  • 原子数组
    • AtomicIntegerArray 、 AtomicLongArray 、AtomicReferenceArray
  • 原子引用
    • AtomicReference 、 AtomicReferenceFieldUpdater 、AtomicMarkableReference(更新带有标记位的引用类型)
  • 原子字段
    • AtomicIntegerFieldUpdater、 AtomicLongFieldUpdater、AtomicStampedReference

AtomicInteger源码分析

  接下来,我们一起来看AtomicInteger源码:

getAndIncrement方法

  调用Unsafe类中的方法。
  Unsafe类相当于Java的后门,使得Java可以像C语言一样直接操作内存空间。当然也会带来弊端 → 指针问题。除了J.U.C包外,Netty、Kafka也使用这个类。这个类提供了很多功能,包括:多线程同步(monitorEnter)、CAS操作(compareAndSwap)、线程的挂起和恢复(park/unpark)、内存屏障(loadFence/storeFence)、内存管理(内存分配、释放内存、获取内存地址等)。

	public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);//每次增加1
    }

  valueOffset → 当前Value变量在内存中的偏移量

 	private static final long valueOffset;

    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

Unsafe.getAndAddInt

	public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
        	//从主内存中获取当前value
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    }

get方法

  get()只需要返回value值就行,这里的value是通过volatile修饰的。

	public final int get() {
        return value;
    }

compareAndSet方法

  compareAndSet()允许客户端基于AtomicInteger实现乐观锁操作。

	public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

你可能感兴趣的:(JavaCore)