Ali p9 tells you what JavaCAS is

1. Introduction to CAS

  1. What is CAS?
        
    The full name of CAS is Compare and Swap, that is, compare and swap. It uses atomic instructions to achieve multi-thread synchronization. It compares the original value stored in the memory address with the specified memory address. Only when they are equal, the specified memory address is exchanged. The expected value and the value in the memory. This operation is an atomic operation. If they are not equal, the original value stored in the memory address is retrieved.

  2. The process of
         CAS CAS is a lock-free algorithm. It has 3 key operands, memory address, the expected value in the old memory, and the new value to be updated. When the memory value is equal to the expected value in the old memory, it will be stored in the memory. The value of is updated to the new value.
    3. Optimistic lock and pessimistic lock
        
    CAS belong to optimistic lock. Optimistic lock is to complete an operation without locking each time but assuming that there is no conflict. If the conflict fails, it will retry until it succeeds.
         Synchronized is a pessimistic lock. After a thread acquires the lock, other threads must wait for the thread to release the lock. The performance is poor.
    Second, the AtomicInteger code demonstrates that
        
    in Java, a++ is not an atomic operation. A simple a++ operation involves three operations. Obtain the memory value of variable a, write variable a+1, and write the new value into memory. Two memory accesses are involved here. If in a multithreaded environment, concurrency safety issues will arise.
        
    AtomicInteger is an atomic operation class, which uses the CAS lock-free algorithm internally.
    Here we analyze its internal implementation.
    AtomicInteger atomicInteger = new AtomicInteger(0);
    atomicInteger.getAndSet(1);
    Copy the code    
    The static code block here is executed before the AtomicInteger object is initialized to obtain the offset of the value field of the AtomicInteger object relative to the "start address" of the AtomicInteger object, Java The layout of the object stored in the memory can be divided into three areas: Header, Instance Data and Padding. The offset of the "start address" is the offset of the object header. .
    static { try {

    valueOffset = unsafe.objectFieldOffset
    (AtomicInteger.class.getDeclaredField("value"));
    } catch (Exception ex) {throw new Error(ex);}
    }
    public final int getAndSet(int newValue) { return unsafe.getAndSetInt( this, valueOffset, newValue); } Copy the code     each time through the memory address (var2) to obtain the original value (var5) in the memory from the memory, and then recycle the original value (var5) in the memory to the given memory address (var2) Compare, if they are equal, update the specified expected value (var4), if they are not equal, try again until it succeeds, and finally return to the old memory value var5. //var1 is the AtomicInteger object, var2 is the memory address value, var4 is the specified expected value public final int getAndSetInt(Object var1, long var2, int var4) { int var5; do { //unsafe.getIntVolatile calls the local method to get the memory Value var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var4));










    return var5;
    }
    Copy code 3. Disadvantages

  3. ABA problem
        
    CAS will check whether the value of the variable has been changed during operation, if not, update the value, but it brings a problem, the first value is A, then it becomes B, and finally it becomes A again. After checking that this value has not been modified, because the final value is still A, but in fact this value has indeed been modified. In order to solve this problem, a version number is added each time an operation is performed, and each operation is two values, a version number and a certain value, and the A——>B——>A problem becomes 1A ——>2B——>3A. The AtomicStampedReference class is provided in jdk to solve the ABA problem. It is implemented with the internal class of Pair. It contains two attributes, which represent the version number and the reference. In compareAndSet, the current reference is checked first, and then the version number flag is checked. Only all The value is updated only if it is equal.

  4. Only the atomic operation of
        
    one shared variable can be guaranteed. When multiple shared variables are operated, the loop CAS cannot guarantee the atomicity of the operation. At this time, locks can be used. Starting from java1.5, the JDK provides the AtomicReference class to ensure the atomicity between referenced objects, and you can put multiple variables in one object to perform CAS operations.

  5. Long cycle time
        
    and high CPU overhead. In the case of high concurrency, if many threads repeatedly try to update a certain variable, but the update is unsuccessful, the cycle will bring great pressure to the CPU.

Guess you like

Origin blog.csdn.net/dcj19980805/article/details/114935459