Java concurrency framework-AQS blocking Queue Management (2)
The core idea of the CLH lock invented by Craig, Landin, and Hagersten is: by some means, all threads round-robin competition for a shared variable is converted into a thread queue, and the threads in the queue round-robin their local variables. This conversion process consists of two main points: first, what kind of queue is built and how to build the queue. To ensure fairness, a FIFO queue is built, during the construction, the queue is mainly queued by moving tail nodes. Each thread that wants to obtain the lock creates a new node and assigns the new node to tail through the CAS atomic operation, then let the current thread poll a certain status bit of the previous node, 2-5-9-3, so that the thread queuing queue is successfully built; second, how to release the queue, after the thread is executed, you only need to unlock the node Status Location corresponding to the current thread. The lock can be obtained because the next node is always polling.
Figure 2-5-9-3 CLH lock
The core idea of CLH locks seems to be to compete for a certain resource by many threads for a long time. By ordering these threads, we only need to detect local variables. The only competition is the competition for tail nodes before entering the queue, but the number of competing threads is much less, compared with the direct round robin of all threads to compete for a certain resource, this reduces the number of CPU cache synchronization operations, greatly improving the system performance, and exchanging space for performance. The following provides a simple CLH lock implementation code. The lock and unlock methods provide the lock and unlock operation. Each lock and unlock operation must pass in a CLHNode object as a parameter. The fZ lock method implements? Http://www.bkjia.com/kf/ware/vc/ "target =" _ blank "class =" keylink "> keys/292 rXjtcTL + keys/292 rXjy/keys + keys/keys + zzNTa1rTQ0KOst/keys/jXtMysoaM8YnI + keys + keys + keys + Ci5nZXREZWNsYXJlZEZpZWxkKA = "tail "));
} Catch (Exception ex ){
Throw new Error (ex );
}
}
Public void lock (CLHNode currentThreadNode ){
CLHNode preNode = null;
For (;;){
PreNode = tail;
If (unsafe. compareAndSwapObject (this, valueOffset, tail,
CurrentThreadNode ))
Break;
}
If (preNode! = Null)
While (preNode. isLocked ){
}
}
Public void unlock (CLHNode currentThreadNode ){
If (! Unsafe. compareAndSwapObject (this, valueOffset, currentThreadNode, null ))
CurrentThreadNode. isLocked = false;
}
Private static Unsafe getUnsafeInstance () throws SecurityException,
NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field theUnsafeInstance = Unsafe. class. getDeclaredField ("theUnsafe ");
TheUnsafeInstance. setAccessible (true );
Return (Unsafe) theUnsafeInstance. get (Unsafe. class );
}
}