Under the influence of the core idea of CLH lock, the basic framework of Java and contract Aqs is designed based on CLH Lock, which is mainly considering that the CLH lock is easier to implement cancellation and timeout function. Compared to the original CLH lock has done a great transformation, mainly from two aspects of the transformation: the structure of the node and the node waiting mechanism. In the structure, the head node and the tail node are introduced, they point to the head and tail of the queue respectively, the attempt to acquire the lock, the queue, the release lock and other implementations are related to the tail-end nodes, and each node introduces the references of the precursor and subsequent nodes, and the wait mechanism is changed from the original spin to the blocking wake. 2-5-9-4, the reference to successive nodes of the predecessor is connected together to form a linked list queue, and the update to the tail and the nodes must be atomic. The following is a detailed look at the queue, detection suspend, release team, timeout, cancellation and other operations.
Figure 2-5-9-4 CLH Queue
① In the queue, the whole logic is actually a CAS operation with an infinite loop, which is the way to compete with spin until it succeeds. The old value of the tail node tail is assigned to the predecessor node of the new node, and the CAs operation is given to the new node node tail, and the successor node of the previous tail node points to the new node. Complete the above steps to build up a list of 2-5-9-4 list queues. The code is simplified as follows:
for (;;) {
Node t = tail;
Node.prev = t;
if (Compareandsettail (t, node)) {
T.next = node;
return node;
}
}
Ii Detection hangs, above we talk about the node waiting mechanism has been aqs by the spin mechanism into a blocking mechanism, a new node after the completion of the queue operation, if it is a spin directly into the loop detection precursor node is the head nodes can, but now be changed to the blocking mechanism, The current thread will first detect if it is a head node and attempt to acquire a lock, and if the current node is a head node and the lock is successfully acquired, it is returned directly, the current thread is not blocked, or the current thread is blocked. The code is simplified as follows:
for (;;) {
if (Node.prev = = head)
If (attempt to get lock succeeded) {
Head=node;
Node.next=null;
Return
}
Blocking threads
}
③ Release the team, the main task of the team is to wake up the waiting queue in the next node, so that all waiting for the node ring ring, each thread in an orderly downward execution. The code is simplified as follows:
Node s = node.next;
Wake-up node s contains the thread
④ Timeout, the Locksupport class's Parknanos method support is required in the support of timeout mode, the thread will wake automatically after blocking for a period of time, each cycle will accumulate time, and when the total consumption time is greater than or equal to the custom timeout time, it will be returned directly. The code is simplified as follows:
for (;;) {
Try to get the lock
if (nanostimeout <= total consumption time)
Return
Locksupport.parknanos (this, nanostimeout);
}
⑤ Cancellation, the queue that waits for a lock may involve a cancel operation due to an outage or a timeout, in which case the canceled node is no longer locked out of contention. The main task of this process is to remove the canceled node, first the node's. First, the node state is set to cancel, and then the predecessor node pred subsequent nodes point to the subsequent nodes of node, here because of the competition, must be through the CAS operation, CAS operation even if the failure also ignore, because has changed the state of the node, The State of the node is looped in the attempt to acquire a lock operation.
Node.waitstatus = node.cancelled;
Node pred = Node.prev;
Node prednext = Pred.next;
Node next = Node.next;
Compareandsetnext (pred, Prednext, next);
Java concurrency framework--aqs blocking Queue Management (iii)--CLH lock retrofit