Java review --- atomic operation class

Starting from JDK1.5, Java has provided us with a series of atomic processing classes: AtomicBoolean, AtomicInteger, AtomicLong, etc., which are mainly used in high-concurrency scenarios to efficiently process programs to simplify synchronization for us.

Let's take AtomicInteger as an example:

AtomicInteger is an Integer class that provides atomic operations. In Java, ++i and i++ are not thread-safe. We inevitably use the synchronized keyword for locking operations when using it. But AtomicInteger provides a thread-safe operation interface:

public final int get() //获取当前的值
public final int getAndSet(int newValue) //获取当前的值,并设置新的值
public final int getAndIncrement() //获取当前的值,并自增
public final int getAndDecrement() //获取当前的值,并自减
public final int getAndAdd(int delta) //获取当前的值,并加上预期的值

After using AtomicInteger, we don't need to lock the numerical operation, so that in the case of non-fierce competition, the overhead is smaller and the speed is faster.

AtomicInteger is essentially implemented through CAS, which mainly maintains three variables:

  • unSafe: A class provided by Java to obtain access to the memory address of an object
  • valueOffset: the offset of the value itself in the memory address, in order to find the address where the data is saved, and to facilitate comparison
  • value: the stored value, this attribute guarantees that it is visible between threads with the help of volatile

When we look at the source code of the incrementAndGet() function of AtomicInteger, we find that the bottom layer of the increment function is unsafe.getAndAddInt().

// ------------------------- JDK 8 -------------------------
// AtomicInteger 自增方法
public final int incrementAndGet() {
    
    
  return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}

// Unsafe.class
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;
}

// ------------------------- OpenJDK 8 -------------------------
// Unsafe.java
public final int getAndAddInt(Object o, long offset, int delta) {
    
    
   int v;
   do {
    
    
       v = getIntVolatile(o, offset);
   } while (!compareAndSwapInt(o, offset, v, v + delta));
   return v;
}

getAndAddInt() loops to obtain the value v at the offset in the given object o, and then determines whether the memory value is equal to v. If they are equal, the memory value is set to v + delta, otherwise it returns false, and the loop continues to retry until the setting is successful, the loop can be exited and the old value is returned. The entire "compare + update" operation is encapsulated in compareAndSwapInt(), which is completed by a CPU instruction in JNI. It is an atomic operation and can ensure that multiple threads can see the modified value of the same variable.

Guess you like

Origin blog.csdn.net/why1092576787/article/details/114702914