, note: Piecemeal knowledge points sorted out only according to one's own understanding (slowly added)
The implementation of synchronous locks in Java relies on the internal queue Synchronizer, which implements the method by which the queue Synchronizer obtains the synchronization state and releases the synchronization state.
Within the queue synchronizer, an INT member variable state is used to indicate whether the status of the synchronization is occupied or released (both shared and exclusive), and when the thread acquires a sync state failure, the line is constructed into a node in the Synchronizer's FIFO queue, blocking the current thread, When the synchronization state is released, the thread of the first node is awakened so that it attempts to obtain the sync state again. Synchronizes the node in the column to save the thread reference, the wait state, and the predecessor and successor nodes that failed the synchronization state.
Failed to get sync status:
The Synchronizer has a first node and a tail node, and when a thread Cheng the sync state (the lock), other threads ready to get the sync state cannot get the sync state, which is then constructed into the tail of the synchronization queue that the node joins to the Synchronizer. This process may have multiple threads requesting to join the tail at the same time, requiring that the insertion of the tail node be atomic, using CAS operations.
First node sync State release:
After the first node releases the Sync synchronization state, the successor node is awakened, and the assembly point sets itself as the initial node when the synchronization state succeeds, because only one line will successfully get the sync state. Therefore, setting the first node does not require a CAS operation to guarantee it.
Condition implementation:
As the internal class of the Synchronizer, because the condition operation needs to obtain the corresponding lock, each condition includes a waiting queue, each node in the queue represents a thread waiting for the condition object, gets the lock thread execution await () the thread releases the lock, The construction node enters the wait state. The Wait queue section reused the node type of the synchronization queue. If the await () method is called without first getting the sync state, the synchronization state is obtained when the lock is released, although its node state default value is 0. However, because information that is not previously available for this thread to obtain the synchronization state is released, it is not the current thread that throws an exception when the thread that owns the synchronization state is checked. (Operations that do not need to get and release the synchronization state in a code block that is not synchronized)
Protected Final Boolean tryrelease (int releases) {
int c = getState ()-releases;
if (Thread.CurrentThread ()!= getexclusiveownerthread ())
throw new Illegalmonitorstateexception ();
Boolean free = false;
if (c = = 0) {Free
= true;
Setexclusiveownerthread (null);
}
SetState (c);
return free;
}
In the condition object, the wait queue, the end node of the queue, and the first node additions and deletions do not require CAs to guarantee atomicity because the thread that operates the Conditon has acquired the lock, which guarantees thread security through the lock.