Java Concurrency CAs detailed

Source: Internet
Author: User

Objective

In high-concurrency applications, the most critical problem is secure access to shared variables, usually through locking, such as synchronized, lock to ensure atomicity, or in some applications, with voliate to ensure the visibility of variables, There is also a copy of the variable by theadlocal, called a local variable (thread-private), and so on. Now we're learning a non-locking mechanism (CAS)

The synchronized and lock we mentioned above are all implemented by locking (pessimistic lock), in fact, the lock is essentially the concurrency into a serial implementation, it is bound to block the execution of the thread, affecting the throughput of the application, and CAS is an optimistic strategy, and does not appear lock to block the execution of the thread.

About CAs

Cas,compare and swap, that is, compare and swap. Atomic Atomic class operations and so on are implemented in CAs, and Concurrenthashmap in JDK1.8 version also adjusted to cas+synchronized

Analysis (native method corresponding to the following in the spin)

There are three parameters in CAs: Memory value V, old expected value A, value to update B. If and only if the value of the memory value v equals the old expected value A, the value of the memory value V is modified to B, otherwise nothing is done

The pseudo code is as follows:

if(this.value == A){    this.value = B    return true;}else{    return false;}
Application

The atomic classes under the Java.util.concurrent.atomic package are all implemented by CAS, and now we take Atomicinteger as an example to analyze the implementation of CAs.

    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); }}private volatile int value;

Unsafe is the core class of CAs, and Java cannot directly access the underlying operating system, but is accessed through the local (native) method. However, the JVM has opened a backdoor: Unsafe, which provides hardware-level atomic operations.

Valueoffset is the offset address of the variable value in memory, and unsafe is to get the original value of the data by the offset address.

Value, using the volatile modifier, to ensure that the same is seen in a multithreaded environment.

Let's use Atomicinteger's Addandget () method to illustrate

    public final int getAndAdd(int delta) {    return unsafe.getAndAddInt(this, valueOffset, delta);}

Internally called the Getandaddint () method of the 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;}

The local method of unsafe is also called in the Getandaddint method.

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

This method is a local method (Java needs to invoke code in other languages, such as C code, which is related to DLL files), with four parameters representing: object, address of object, expected value, modified value

CAS defects
    • An optimistic lock can only guarantee the atomic operation of a shared variable. As the example above, the spin process can only guarantee the atomicity of the value variable, if more than one or several variables, optimistic lock will become powerless, but the mutex can be easily resolved, regardless of the number of objects and the size of the object granularity.

    • Long spins can lead to high overhead. If CAS has been spinning for long periods of time, it will cost the CPU a lot.

    • ABA problem. The core idea of CAS is to determine if the memory value is changed by the same as the memory value and the expected value, but this judgment logic is not rigorous, if the memory value is a, then a thread changed to B, and finally changed to a, then the CAS think this memory value has not changed, but actually there are other threads changed, This situation has a significant impact on the results of the operation of a scenario that relies on process values. The idea is to introduce a version number, and each time the variable is updated, the version number is added one.

The difference between synchronized and CAS
    • For less competitive resources, the use of synchronized synchronization lock for thread blocking and wake-up switching and user-mode kernel state switching operation additional waste of CPU resources, and CAS based on hardware implementation, do not need to enter the kernel, do not need to switch threads, the operation spin probability is less, Therefore, higher performance can be achieved.

    • In the case of serious resource competition, the probability of CAS spin is larger (such as the do-while cycle in the Getandaddint method), which wastes more CPU resources and is less efficient than synchronized.

Java Concurrency CAs detailed

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.