Based on its 12

The purpose of this article is to provide an introduction for the analysis of LongAdder in the following articles, so that the two can be compared.

Atomic Package resolution reference (e.g. LazySet principle resolution)

Java Concurrent Atomic Package

Common AtomicLong methods are as follows:

  • Long addAndGet(Long delta) : Atomically adds the input value to the value in the instance (the value in the AtomicLong) and returns the result.
  • CompareAndSet (long expectedValue, long newValue) : if the input value is equal to the expectedValue, the atomic formula sets the value to the input value.
  • Long getAndIncrement() : Increments the current value atomically by 1.
  • Void lazySet(long newValue) : Eventually set to newValue. Using lazySet to set the value may cause other threads to read the old value for a short time later.
  • Long getAndSet(Long newValue) : The value set atomically to newValue and returns the old value.

The AtomicLong sample code looks like this:

public class AtomicLongTest { static AtomicLong ai = new AtomicLong(1); public static void main(String[] args) { System.out.println(ai.getAndIncrement()); System.out.println(ai.get()); }}Copy the code

The following output is displayed:

1
2
Copy the code

So how does getAndIncrement implement atomic operations? GetAndIncrement getAndIncrement getAndIncrement getAndIncrement

public final long getAndIncrement() {
   return U.getAndAddLong(this, VALUE, 1L);
}
@HotSpotIntrinsicCandidate
public final long getAndAddLong(Object o, long offset, long delta) {
    long v;
    do {
        v = getLongVolatile(o, offset);
    } while(! weakCompareAndSetLong(o, offset, v, v + delta));return v;
}
/** Volatile version of {@link #getLong(Object, long)} */
@HotSpotIntrinsicCandidate
public native long getLongVolatile(Object o, long offset);

@HotSpotIntrinsicCandidate
public final boolean weakCompareAndSetLong(Object o, long offset,
                                           long expected,
                                           ong x) {
    return compareAndSetLong(o, offset, expected, x);
}
/**
 * Atomically updates Java variable to {@code x} if it is currently
 * holding {@code expected}.
 *
 * <p>This operation has memory semantics of a {@code volatile} read
 * and write.  Corresponds to C11 atomic_compare_exchange_strong.
 *
 * @return {@code true} if successful
 */
@HotSpotIntrinsicCandidate
public final native boolean compareAndSetLong(Object o, long offset,
                                              long expected,
                                              long x);
Copy the code

@ HotSpotIntrinsicCandidate JDK source, be @ HotSpotIntrinsicCandidate labeling method, a set of effective implementation in HotSpot, the efficient implementation based on CPU instructions and runtime, The efficient implementation of HotSpot maintenance replaces the source implementation of the JDK for greater efficiency.

Source getAndAddLong(Object O, long offset, long delta) in the do while loop body is the key to achieve, its logic is: The first step is to obtain the value stored in AtomicLong. The second step is to add 1 to the current value of AtomicLong. The third step is to use weakCompareAndSetLong method to carry out atomic update operation, which first checks whether the current value is equal to V. Equal means that the AtomicLong value has not been modified by other threads, so update the current value of weakCompareAndSetLong to the value of V +delta. If it is not equal to v, weakCompareAndSetLong returns false. The program will enter the do while loop to perform weakCompareAndSetLong operation again.

The implicit problem here is that when contention for a shared variable (let’s say the name of the variable is A) is intense, the value of A will be changed by another thread between reading a and changing a, causing the current thread to keep retrying (spin) and occupying the CPU.

This leads to another problem, serial is the best solution when lock preemption is intense. Use synchronized, for example.

Java. Util. Concurrent. Atomic atomic operation is based on the basic of the Unsafe or VarHandle.

AtomicLong source

This article refers to the art of Java Concurrent Programming by Fang Tengfei, Wei Peng and Cheng Xiaoming

Personal wechat official Account:

Personal CSDN blog:

blog.csdn.net/jiankunking

Personal Nuggets blog:

Juejin. Cn/user / 255931…

Individual making:

github.com/jiankunking

Personal Blog:

jiankunking.com