The underlying implementation principle of Java concurrency mechanism

Lock expansion process

PrerequisitesCAS

Hardware support for concurrency

The approach taken in most processor architectures (including IA32 and Sparc) is to implement a compare-and-swap (CAS) instruction. CAS consists of 3 operands - the memory location (V), the expected original value (A), the The new value (B) written, if and only if V == A, CAS will atomically update (V) the original value with the new value (B), whether the operation is successful or not, it will return ( V) value, and the whole process is uninterrupted, so CAS is an atomic operation; it mainly uses the CAS instruction of the CPU, and uses JNI to complete the non-blocking algorithm of Java.

Simulate CAS operation

public class SimpleCAS {

    private Integer value;

    private synchronized int get(){
        return value;
    }
    private synchronized int compareAndSwap(int a, int b){
        int v = value;
        return v == a ? b : v;
    }
    class CasCounter{
        private SimpleCAS simpleCAS;
        private Integer getValue(){
            return simpleCAS.get();
        }
        private Integer increment(){
            Integer v;
            do {
                v = simpleCAS.get();
            }
            while (v != simpleCAS.compareAndSwap(v,  v + 1));
            return v + 1;
        }
    }
}

Preliminary knowledge fair lock & unfair lock

Fair lock: When locking for the first time, he will not try to lock. He will check to see if anyone is queuing in front of me. If there is a queue, I will queue first. After entering the queue, if the person in front It is the head node, he will try to lock again, execute the synchronization code block if successful, and park if it fails (really queued);

Unfair lock: He will first grab the lock when the lock method is called. If it fails, he will go to see why it failed (whether the lock is held by someone). If no one holds it, the unfair lock will be It will be locked directly (it will not judge whether someone is queued), if it succeeds, it will enter the synchronization code block, and if it fails, it will enter the queue.

flow chart

 

About how the queue is designed and formed

 1. Main attributes of AQS class design

private transient volatile Node head;/队首
private transient volatile Node tail;//队尾
private volatile int state;//锁状态标识

2. Design of Node class

static final class Node {
        volatile Node prev;
        volatile Node next;
        volatile Thread thread;
}

The synchronizer contains references of two types of nodes, one points to the head node, and the other points to the tail node. The thread that fails to obtain the synchronization state will become the node and join the tail of the queue.

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324131227&siteId=291194637