Soul concurrent programming: CAS mechanism Detailed

Java provides many classes atomic operations to ensure atomicity operation shared variables. These underlying principles are the use of atomic operations CAS mechanism. Before using a technique to understand the underlying principle of this technology is very important, so this article will first say something about what is the mechanism of CAS, CAS number of problems and how to use the mechanism in Java CAS mechanism.

In fact, the cornerstone of Java concurrency framework of a total of two, one CAS is described in this article, is another piece of AQS, writing articles will follow presentation.

What is the mechanism of CAS

CAS is a mechanism for data updates. Specifically what is before CAS mechanism, let's talk about the next in a multithreaded environment, shared variable data updates in two modes: pessimistic and optimistic locking mode lock mode.

Update pessimistic locking manner that: when updating data in a high probability there will be other threads to compete for shared resources, pessimistic locking approach is: first access to resources thread will lock up resources, not compete for resources other thread only enter blocking queue, ranking a thread releases the lock access to resources after these threads can have a chance to compete for resources. java is synchronized in a typical implementation pessimistic locking, synchronized very simple and convenient to use, but will not compete for resources to thread into the blocked state, the thread between the blocking state and the Runnable state a lower switching efficiency (slower). For instance, your update is actually very fast, in which case you will be synchronized with other threads are locked, the thread from Runnable Blocked state switch back to China in time may be longer than the time you update.

Update optimistic locking manner that: the probability update data when the other threads compete for the shared variable is very small, so when updated data is not locked to share data. But before the official update data checks whether the data is changed by other threads, other threads if not changed will be updated to the latest value of the shared variable, if you find a shared variable has been updated over the other thread, it retries until it succeeds until. CAS is optimistic locking mechanism of a typical implementation.

CAS, a Compare and Swap short, there are three core parameters in this mechanism:

  • The value stored in main memory shared variable: V (V is the memory address value under normal circumstances, the value of the memory address may be obtained by this)
  • A copy of the value of the shared variable working memory, also called the expected value: A
  • Shared variables need to be updated to the latest value: B

Soul concurrent programming: CAS mechanism Detailed

In above figure, the V values ​​stored in main memory, first thread to read the value V from main memory to the working memory of the thread A in the V value, and then calculated into the value B, and finally the write-back value B V value into memory. A plurality of V values ​​are common threads doing so. CAS before the core of the B value is written to compare A to V and V values ​​are the same, if not identical, to prove this point V value has been changed by other threads, to re-assign the value of V A, B and recalculated , if the same, then the value is assigned V. B

It is noted that this step CAS mechanisms atomic steps (from atomic level instructions provided), it can solve the atomic mechanism CAS multithreaded programming concurrent reads and writes to shared variables.

CAS mechanism advantages and disadvantages

Shortcoming

1. ABA problem
ABA question: CAS in value when the operation will check whether a variable is changed, if not then the updated value, but poses a problem, the beginning value is A, then becomes B, and finally become the A. After checking this value does not changed, because the final value or A, but in fact this value has indeed been modified. To solve this problem, each time the operation plus a version number, each operation is two values, a version number and a value, A -> B -> A question then becomes 1A -> 2B -> 3A. Provide in jdk in a class AtomicStampedReference ABA solve problems and achieve Pair this with the internal class contains two properties, representing the version number and references, references to the current compareAndSet check in, and then sign a check for the version number, and only all equal value is updated.

2. may consume higher CPU
looks CAS high efficiency ratio locks, into a non-blocking mechanism from the blocking mechanism, reducing the waiting time between threads. Each method can not be absolutely better than another, a large degree of competition between the threads of time, if the use of CAS, each thread has a lot of competition, that CAS mechanism can not be updated successfully. In this case CAS will always retry mechanism, which would consuming CPU. So you can see, if the small degree of competition between threads, using CAS is a good choice; but if a lot of competition, the use of locks might be a better choice. In very high concurrency environments, if you still want to update by atom type, you can use AtomicLong alternative class: LongAdder.

3. does not guarantee the atomicity of code blocks
CAS mechanism in Java shared variable can guarantee the atomicity operation, and can not guarantee the atomicity of code blocks.

advantage

  • We can guarantee the atomicity operation variable;
  • Concurrent amount is not very high, higher than the mechanism used CAS efficient locking mechanism;
  • In the case of shared resource thread a short time, the use of CAS mechanism efficiency will be higher.

CAS operation --Unsafe class Java classes offered

From the beginning Java5 introduces support for the underlying mechanism of CAS, before that requires developers to write code that can only be achieved CAS. Atomic atomic variable classes (e.g. AtomicInteger, AtomicLong) CAS operation can see the code, where the code is called (method core native code calls modified) underlying implementation. GetAndSet can see the relationship between the method and the source code AtomicInteger compareAndSet methods, compareAndSet method calls the underlying implementation, the method may be implemented with a volatile read and write to the same variable effect. In said before, for example, volatile i ++ does not support such a combined operation, in Atomic provided a method of implementing the operation. JVM support for CAS by these atoms class (Atomic ***) is exposed for us to use.

Atomic underlying system while class category Unsafe call is the API classes, class Unsafe compareAndSwap * provides a series of methods, the following brief introduction Unsafe class API:

  • When using the specified return variable memory offset address within the class, the only access to the specified offset address field of the Unsafe function: long objectFieldOffset (Field field) method. Unsafe use the following code in the class acquisition variable value AtomicLong object memory offset.
    static {
    try {
       valueOffset = unsafe.objectFieldOffset
           (AtomicInteger.class.getDeclaredField("value"));
    } catch (Exception ex) { throw new Error(ex); }
    }
  • int arrayBaseOffset (Class arrayClass) Method: obtaining an address of the first element of the array.
  • int arrayIndexScale (Class arrayClass) Method: obtaining an array element occupies a byte.
  • boolean compareAndSwapLong (Object obj, long offset, long expect, long update) Method: Comparison of object obj is the offset value of a variable equal to expect whether the offset is equal to the update using the update value, and then returns true, otherwise returns false.
  • public native long getLongvolatile (Object obj, long offset) Method: Gets the value of the object obj offset volatile variable offset corresponding semantics.
  • void putLongvolatile (Object obj, long offset, long value): Set the type of object obj offset drift to a long value of field value, to support volatile semantics.
  • void putOrderedLong (Object obj, long offset, long value): Set obj object type field offset long offset value corresponding to the value. This is a method putLongvolatile delay, and does not guarantee the value of modification immediately visible to other threads. Only use volatile variables and modifications will be expected to use this method if accidental modification.
  • void park (boolean isAbsolute, long time) method: blocking the current thread, which isAbsolute parameter equal to false and the time equal to 0 has been blocked. time is greater than 0 indicates that after the specified time block the thread will be awakened, this time is a relative value, a delta value is relative to the current time after accumulating time the current thread will be awakened. If isAbsolute equal to true, and the time is greater than 0, it means that the blocked thread to the specified point in time will be awakened, where time is an absolute time, is converted into a point in time after ms value. In addition, when another thread calls the current interrupt method blocks thread interrupted the current thread, the current thread will return, and when the other thread calls unPark method and the current thread as a parameter the current thread will return.
  • void unpark (Object thread) method: wake-up call park blocked thread.

The following new functions are JDK8, Long Here, only the type of operation.

  • long getAndSetLong (Object obj, long offset, long update) Method: acquiring object obj in the offset value of offset current variable semantic volatile, volatile and set the variable semantic value update.

    //这个方法只是封装了compareAndSwapLong的使用,不需要自己写重试机制
    public final long getAndSetLong(Object var1, long var2, long var4) {
    long var6;
    do {
        var6 = this.getLongVolatile(var1, var2);
    } while(!this.compareAndSwapLong(var1, var2, var6, var4));
    
    return var6;
    }
  • long getAndAddLong (Object obj, long offset, long addValue) Method: acquiring object obj in the offset value of offset current variable semantic volatile, and set the variable value of the original value + addValue, similar principles and methods above.

CAS usage scenarios

  • Use a variable amount of access statistics website;
  • Atomic operation class;
  • Updated database optimistic locking.

Guess you like

Origin blog.51cto.com/14230003/2465259