Atomic class -- Analysis of AtomicInteger principle

This section focuses on the use and principle of Atomic classes led by Atomic.

Atomic operation

Atomic operation refers to the operation that will not be interrupted by the thread scheduling mechanism. Once the operation starts, it runs until the end, and there will be no thread context switch in the middle.

Atomic operation can be one step or multiple steps, but its order can not be disrupted, nor can it be cut to only execute a part of it. It is the core feature of atomicity to regard the whole operation as a whole.

Atomic class

There are many atomic classes in java, which are divided into four main categories.

Atomic update base type or reference type

  1. AtomicBoolean

Atomic update boolean type, internal use of int type value store 1 and 0 for true and false, the underlying is also the atomic operation of int type.

  1. AtomicInteger

Atom update int type.

  1. AtomicLong

Atom update long type.

  1. AtomicReference

The atom updates the reference type to specify the class to operate on through generics.

  1. AtomicMarkableReference

The atom updates the reference type, and internally uses Pair to carry the reference object and whether it has been updated, which avoids the ABA problem.

  1. AtomicStampedReference

Atomic update reference type, internal use of Pair to carry reference object and update postmark, avoid ABA problem.

Atoms update elements in an array

The atom updates the elements in the array, which can update the elements at the specified index position in the array. These classes mainly include:

  1. AtomicIntegerArray

Atoms update elements in an int array.

  1. AtomicLongArray

Atoms update elements in a long array.

  1. AtomicReferenceArray

Atoms update elements in the Object array.

Fields in atomic update objects

The fields in the atomic update object can update the fields with the specified field names in the object. These classes mainly include:

  1. AtomicIntegerFieldUpdater

Atom updates the int type field in the object.

  1. AtomicLongFieldUpdater

Atom updates the long type field in the object.

  1. AtomicReferenceFieldUpdater

Atom updates the reference type field in the object.

High performance atom class

High performance atomic classes are added in java8. They use the idea of segmentation, update different thread hash to different segments, and finally add the values of these segments to get the final values. These classes mainly include:

  1. Striped64

The parent of the following four classes.

  1. LongAccumulator

A long type aggregator needs to pass in a long type binary operation, which can be used to calculate various aggregation operations, including addition and multiplication.

  1. LongAdder

Long type accumulator, a special case of long accumulator, can only be used to calculate addition, and it starts from 0.

  1. DoubleAccumulator

A double type aggregator needs to pass in a double type binary operation, which can be used to calculate various aggregation operations, including addition and multiplication.

  1. DoubleAdder

Double type accumulator, a special case of double accumulator, can only be used to calculate addition, and it starts from 0.

Atomic interview questions

The reason for the epidemic in the beginning of 2020 is that it's time for Jin, San, yin and Si, so I have prepared common interview questions for you.

About the problem of atomic class, unparalleled teacher sorted out the following:

(1) What is Unsafe?

(3) Why is Unsafe?

(4) How to obtain the instance of Unsafe?

(5) CAS operation of Unsafe?

(6) Unsafe blocking / wakeup operation?

(7) Unsafe instantiates a class?

(8) Six ways to instantiate a class?

(9) What is atomic operation?

(10) What is the relationship between atomic operations and A in database ACID?

(11) How does AtomicInteger implement atomic operation?

(12) What problems does AtomicInteger solve?

(13) What are the disadvantages of AtomicInteger?

(14) What is ABA?

(15) The harm of ABA?

(16) ABA solution?

(17) How does atomicstampededreference solve ABA?

(18) Have you ever encountered ABA problems in your work?

(19) What is the cache architecture of CPU?

(20) What is the CPU's cache line?

(21) what is the memory barrier?

(22) what is the cause of pseudo sharing?

(23) how to avoid false sharing?

(24) eliminate the application of pseudo sharing in java?

(25) how to implement LongAdder?

(26) how does LongAdder eliminate pseudo sharing?

(27) performance comparison between LongAdder and AtomicLong?

(28) is the cell array in LongAdder infinitely expanded?

AtomicInteger using

package com.example.atomic.atomicinteger.demo;
import	java.util.concurrent.atomic.AtomicInteger;


/**
 * @Author: Unparalleled teacher [cloud analysis college: http://yunxiedu.net QQ:3190976240 email:zhouguanya20@163.com]
 * @Date: 2020-03-21 16:20
 * @Description: AtomicInteger Usage mode
 */
public class AtomicIntegerDemo {

    public static void main(String[] args) throws InterruptedException {
        test1();
        test2();
    }

    private static void test1() throws InterruptedException {
        Counter counter = new Counter();
        // 100 threads
        for (int i = 0; i < 10; i++) {
            // Each thread accumulates count 10 times
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    counter.addCount();
                }
            }).start();
        }
        Thread.sleep(1000);
        System.out.println("count = " + counter.getCount());
    }

    private static void test2() throws InterruptedException {
        /**
         * Atomic int
         */
        AtomicInteger count = new AtomicInteger();
        // 100 threads
        for (int i = 0; i < 10; i++) {
            // Each thread accumulates count 10 times
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    count.incrementAndGet();
                }
            }).start();
        }
        Thread.sleep(1000);
        System.out.println("count = " + count.get());
    }
}


/**
 * volatile Decorated counter
 */
private volatile static int count = 0;

public void addCount() {
	count++;
}

public int getCount() {
	 return count;
}

AtomicInteger principle

AtomicInteger declaration

public class AtomicInteger extends Number implements java.io.Serializable

Use of Unsafe class

// 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); }
}

AtomicInteger property

 private volatile int value;

AtomicInteger constructor

    /**
     * Creates a new AtomicInteger with the given initial value.
     *
     * @param initialValue the initial value
     */
    public AtomicInteger(int initialValue) {
        value = initialValue;
    }

    /**
     * Creates a new AtomicInteger with initial value {@code 0}.
     */
    public AtomicInteger() {
    }

AtomicInteger auto increment

    /**
     * Atomically increments by one the current value.
     *
     * @return the updated value
     */
    public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }
	

The method to call the Unsafe class is as follows.

    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;
    }

Note that compareAndSwapInt is to modify int value in CAS mode.

The principle of autoincrement of AtomicInteger.incrementAndGet method:

  1. Call the unsafe.getAndAddInt method
  2. The unsafe.getAndAddInt method accumulates the original value through CAS method in the way of spin. If the accumulation fails, the next cycle will be entered. If the accumulation succeeds, the spin ends.

Tags: Programming Java Database

Posted on Sun, 22 Mar 2020 03:57:57 -0400 by jdwmk