[Concurrent programming] --- Compare And Swap (CAS) Principle Analysis

Source Address: https://github.com/nieandsun/concurrent-study.git


1 What is CAS?


1.1 CAS different principles locking and solve the problem of atomicity

First, look at the following code:

package com.nrsc.ch2.cas;

import java.util.ArrayList;
import java.util.List;

public class CasDemo {

    //共享资源
    static int i = 0;

    public static void increase() {
        i++;
    }

    public static void main(String[] args) throws InterruptedException {
        Runnable r = () -> {
            for (int j = 0; j < 1000; j++) {
                increase();
            }
        };

        List<Thread> threads = new ArrayList<>();
        for (int j = 0; j < 10; j++) {
            Thread thread = new Thread(r);
            threads.add(thread);
            thread.start();
        }

        //确保前面10个线程都走完
        for (Thread thread : threads) {
            thread.join();
        }

        System.out.println(i);
    }
}

I believe everyone knows the code due i++不是原子操作, thus leading to the final result of the 10 threads of execution than 10 * 1,000 = 10,000.
Of course, I believe almost everyone knows by 加锁可以解决这个问题, locking principle to resolve the basic problem can be profiled using the following figure:
Here Insert Picture Description
but in fact in addition to the use of CAS locking mechanism can solve this problem. In addition, since it is locked Another solution, 那它肯定是无锁的and therefore the use of CAS mechanism to solve the problem of way can be roughly profile with the following figure:
Here Insert Picture Description
that in the end what it is CAS? How does it do to solve this problem?


1.2 CAS Principle Analysis

Look at the definition (taken from Baidu Encyclopedia):

compare and swap, a lock solution multithreading performance loss caused by a mechanism of a parallel case, CAS operation includes three operands - a memory location (V), is expected to original value (A) and the new value (B). If the memory location of the original value matches the expected value, then the processor will automatically update the location value to the new value. Otherwise, the processor does nothing. In either case, it returns the value of the position before the CAS instruction. CAS effectively explained“我认为位置V应该包含值A;如果包含该值,则将B放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。"

Then draw a diagram to explain:
Here Insert Picture Description


2 CAS possible problems


2.1 ABA problem

CAS new to tell the truth when, in fact, I think the ABA problem. ☺☺☺

By 1.2 may know, at the time of the operation required CAS value, check the value has not changed, if not changed is updated, but if a value is A, became a B, he is a A, then use the CAS You will find its value has not changed, but actually change the check - which is called the ABA problem>.

For example popular point, you pour a glass of water put on the table, did something else, and then you drink a colleague gave you back a glass of water, you still come back to see the water, get up to drink , no matter if you are middle water people drink, only water is still concerned about, okay; but if you are a more hygienic speaking people, then you certainly upset. . .

Solutions ABA problem is actually very simple, is to use the version number. In front of the additional variable version number, each time the variable update version number is incremented by 1, then A → B → A becomes 1A → 2B → 3A up.


2.2 large overhead long cycle times

If the time is not successful spin CAS, it will bring a very large CPU execution cost.


2.3 atomic operation to ensure that only a shared variable

When performing operations on a shared variable, we can use the CAS cycle approach to ensure an atomic operation, but 对多个共享变量操作时,循环CAS就无法保证操作的原子性,this time we can 用锁.

There is also a tricky way, is to merge multiple shared variables into a shared variable to operate. For example, there are two shared variables i = 2, j = a, merge at ij = 2a, and to operate with CAS ij. Starting from Java 1.5, JDK classes AtomicReference provided to ensure the reference atom between objects can be variable in the plurality of objects in a CAS operation is performed.


3 JDK support for the CAS - unsafe class

java provides support for the CAS operation, in particular in sun.misc.unsafe class, declare as follows:

public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);

public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);

The parameters of the above meanings:

  • Parameters var1: represents the object to be operated
  • Parameters var2: indicates the offset address of the object property to be operated
  • Parameters var4: a value representing a desired data needs to be modified
  • Parameters var5 / var6: To modify the new mine represents a value of

注意:Unsafe class has the ability to make Java language like C pointers as operating memory space, it also brings problems pointer. Excessive use of Unsafe class will make the chance of error becomes large, and therefore does not recommend the use of Java official, almost no official document. Unsafe object can not be called directly, only through reflection.


The 4 JDK classes associated atomic operations Introduction - CAS mechanisms underlying


4.1 AtomicInteger

  • int addAndGet (int delta): Numerical Example Atomically input value (inside of AtomicInteger value) are added, and returns the result.
  • boolean compareAndSet (int expect, int update): If the input value is equal to the expected value Atomically set the value of the input value.
  • int getAndIncrement (): Atomically current value plus 1, note that this is the return value before increment.
  • int getAndSet (int newValue): atomically newValue set to a value of, and return the old value.

4.2 AtomicIntegerArray

The main way to provide atomic update integer array, which is used as follows.

  • int addAndGet (int i, int delta): atomically input values ​​to the array element at index i is added.
  • boolean compareAndSet (int i, int expect, int update): If the current value is equal to the expected value, the elements of the array Atomically i is set to update the position values.

Note that, by constructing an array of value passed into the method, then AtomicIntegerArray will present a copy of the array, so when AtomicIntegerArray array element internal modifications will not affect the incoming array.


4.3 update reference types

Atomic update basic types of AtomicInteger, can only update a variable, if you want to update multiple atomic variables, you need to use this class reference type atomic updates provided. Atomic package provides the following three classes.

  • AtomicReference
    atomic update reference type.
  • AtomicStampedReference
    利用版本戳的形式记录了每次改变以后的版本号,这样的话就不会存在ABA问题了。这就是AtomicStampedReference的解决方案。AtomicMarkableReference跟AtomicStampedReference差不多, AtomicStampedReference是使用pair的int stamp作为计数器使用,AtomicMarkableReference的pair使用的是boolean mark。 还是那个水的例子,AtomicStampedReference可能关心的是动过几次,AtomicMarkableReference关心的是有没有被人动过,方法都比较简单。
  • AtomicMarkableReference:
    atomic update flag set with a reference type. Atom may update a boolean flag and reference types. Constructor is AtomicMarkableReference (V initialRef, booleaninitialMark).

4.4 atomic update field class

If the need to update a field of a class of atoms, the atoms need to use field-based update, Atomic package provides the following three classes atoms field update.
To update atomically field class requires two steps. The first step, because the atomic update field classes are abstract classes, each time using a static method used must newUpdater () to create an updater, and the need to set up classes and attributes you want to update. The second step,更新类的字段(属性)必须使用public volatile修饰符。

  • AtomicIntegerFieldUpdater:
    atomic update updater integer field.
  • AtomicLongFieldUpdater:
    atomic update updater long integer field.
  • AtomicReferenceFieldUpdater:
    atomic update reference types in the field.

Published 216 original articles · won praise 284 · views 490 000 +

Guess you like

Origin blog.csdn.net/nrsc272420199/article/details/105032873