An overview of

Atomic operations are operations that are not interrupted by thread scheduling mechanisms and that, once started, run through to completion without any thread context switching.

An atomic operation can be a single step or multiple steps, but the sequence can not be disrupted, nor can it be cut up to perform only a part of it. Seeing the whole operation as a whole is a core characteristic of atomicity.

There are many atomic classes available in Java, and I’ll focus on four categories.

Atom updates base or reference types

If it is a basic type, the value is replaced, and if it is a reference, the reference address is replaced. These classes mainly include:

(1) AtomicBoolean

Atoms update Boolean types, internally using values of type int to store 1 and 0 for true and false, and underlying atomic operations on types of type int.

(2) AtomicInteger

Atom updates int type.

(3) the AtomicLong

Atom updates the long type.

(4) AtomicReference

Atom updates the reference type, specifying the class to operate on via generics.

(5) AtomicMarkableReference

Atomic update reference types, internally using pairs to carry reference objects and whether or not they have been updated, avoiding ABA problems.

(6) AtomicStampedReference

Atomic update reference types, internal use of Pair to carry reference objects and updated postmarks, avoiding ABA problems.

Unsafe, the underlying declaration is to call compareAndSwapXxx(), and the underlying declaration is as follows:

private static void testAtomicReference(a) {
    AtomicInteger atomicInteger = new AtomicInteger(1);
    atomicInteger.incrementAndGet();
    atomicInteger.getAndIncrement();
    atomicInteger.compareAndSet(3.Awesome!);
    System.out.println(atomicInteger.get());

    AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(1.1);
    atomicStampedReference.compareAndSet(1.2.1.3);
    atomicStampedReference.compareAndSet(2.Awesome!.3.5);
    System.out.println(atomicStampedReference.getReference());
    System.out.println(atomicStampedReference.getStamp());
}
Copy the code

Atoms update elements in an array

Atomic update an element in an array. You can update an element at a specified index position in the array.

(1) AtomicIntegerArray

Atom updates elements in an int array.

(2) AtomicLongArray

Atoms update elements in the LONG array.

(3) the AtomicReferenceArray

Atom updates elements in the Object array.

When you update an element, you must specify the index position in the array.

private static void testAtomicReferenceArray(a) {
    AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(10);
    atomicIntegerArray.getAndIncrement(0);
    atomicIntegerArray.getAndAdd(1.Awesome!);
    atomicIntegerArray.incrementAndGet(2);
    atomicIntegerArray.addAndGet(3.Awesome!);
    atomicIntegerArray.compareAndSet(4.0.Awesome!);
    
    System.out.println(atomicIntegerArray.get(0));
    System.out.println(atomicIntegerArray.get(1));
    System.out.println(atomicIntegerArray.get(2));
    System.out.println(atomicIntegerArray.get(3));
    System.out.println(atomicIntegerArray.get(4));
    System.out.println(atomicIntegerArray.get(5));
}
Copy the code

Atomically update fields in an object

Atomic update object in the field, can update the object specified field name of the field, these classes mainly include:

(1) AtomicIntegerFieldUpdater

Atom updates a field of type int in an object.

(2) AtomicLongFieldUpdater

Atom updates a field of type long in an object.

(3) the AtomicReferenceFieldUpdater

Atom update reference type field in object.

The operation of these classes is basically similar, all need to pass in the name of the field to update, the basic usage is as follows:

private static void testAtomicReferenceField(a) {
    AtomicReferenceFieldUpdater<User, String> updateName = AtomicReferenceFieldUpdater.newUpdater(User.class, String.class,"name");
    AtomicIntegerFieldUpdater<User> updateAge = AtomicIntegerFieldUpdater.newUpdater(User.class, "age");

    User user = new User("tong ge".21);
    updateName.compareAndSet(user, "tong ge"."read source code");
    updateAge.compareAndSet(user, 21.25);
    updateAge.incrementAndGet(user);
    
    System.out.println(user);
}

private static class User {
    volatile String name;
    volatile int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString(a) {
        return "name: " + name + ", age: "+ age; }}Copy the code

High performance atomic class

High performance atomic classes are added to Java8. They use the idea of segmentation, and hash different threads into different segments to update, and finally add the values of these segments to get the final value. These classes include:

(1) Striped64

The parent classes of the following four classes.

(2) LongAccumulator

An aggregator of type long requires passing in a binary operation of type LONG, which can be used to evaluate various aggregation operations, including addition and multiplication.

(3) the LongAdder

An accumulator of type long, a special case of LongAccumulator, can only be used to add and is counted from 0.

(4) DoubleAccumulator

An aggregator of type double, passing in a binary operation of type double, can be used to calculate various aggregate operations, including addition and multiplication.

(5) DoubleAdder

An accumulator of type double, a special case of DoubleAccumulator, can only be used to add and is counted from 0.

DoubleAccumulator and DoubleAdder are both long and long.

private static void testNewAtomic(a) {
    LongAdder longAdder = new LongAdder();
    longAdder.increment();
    longAdder.add(Awesome!);
    System.out.println(longAdder.sum());

    LongAccumulator longAccumulator = new LongAccumulator((left, right)->left + right * 2.Awesome!);
    longAccumulator.accumulate(1);
    longAccumulator.accumulate(3);
    longAccumulator.accumulate(-4);
    System.out.println(longAccumulator.get());
}
Copy the code

The problem

About atomic problems, the author sorted out the following:

(1) What is Unsafe?

(3) What is Unsafe about food?

(4) How to obtain an instance of Unsafe?

(5) Unsafe CAS operation?

(6) Unsafe blocking/wake up?

(7) Unsafe instantiates a class?

(8) Six ways to instantiate a class?

(9) What is atomic operation?

(10) The relation between atomic operation and A in database ACID?

(11) How does AtomicInteger implement atomic operation?

(12) What problem does AtomicInteger mainly solve?

(13) What are the disadvantages of AtomicInteger?

(14) What is ABA?

(15) Harm of ABA?

(16) ABA solution?

(17) How does AtomicStampedReference solve ABA?

(18) Have you encountered ANY ABA problems in actual work?

(19) What is the cache architecture of CPU?

(20) What are the CPU’s cache rows?

(21) What is the memory barrier?

(22) What is the cause of false sharing?

(23) How to avoid fake sharing?

(24) Eliminate pseudo-sharing in Java?

(25) How to realize LongAdder?

(26) How does LongAdder eliminate fake sharing?

(27) Performance comparison between LongAdder and AtomicLong?

Is the array of cells in LongAdder infinite?

That’s about it. Can you answer them all? Click the link below to go directly to the corresponding chapter:

Unsafe parsing of Java magic classes

Dead ke Java atomic class AtomicInteger source analysis

Dead knock Java atom class AtomicStampedReference source code analysis

What is False sharing?

Dead knock Java atomic class LongAdder source analysis

eggs

Atomic class series source code analysis to this end, although the analysis of the analogy is less, but the content is very much involved, especially the underlying knowledge of the operating system, such as CPU instructions, CPU cache architecture, memory barrier, etc.

In the next chapter, we’ll dive into the synchronization series, where the most common type of synchronization is locking, focusing on the various locks in Java, the various synchronizers, and distributed locking.


Welcome to pay attention to my public number “Tong Elder brother read source code”, view more source code series articles, with Tong elder brother tour the ocean of source code.