ReentrantLock is implemented internally by Sync class instances.
The Sync class is defined inside ReentrantLock.
Sync inherits from AbstractQueuedSynchronizer.
AbstractQueuedSynchronizer inherits from AbstractOwnableSynchronizer.
Only an exclusiveOwnerThread variable is defined in the AbstractOwnableSynchronizer class, representing the thread currently owned.
In addition to the Sync class, ReentrantLock also defines two implementation classes internally.
NonfairSync is an unfair lock. FairSync is a fair lock.
The two constructs of ReentrantLock are as follows:
ReentrantLock lock method
Unfair lock method
The compareAndSetState method is a CAS method. This method attempts to update a variable in the object. The variable expects to be 0, updated to 1.
If the update is successful, set the exclusiveOwnerThread variable to the current thread. Then the lock method will return immediately.
If the update fails, acquire(1) is called.
In the acquire method, tryAcquire() is called first and try to update again.
The tryAcquire() method of unfair lock is as follows:
The nonfairTryAcquire() method of the unfair lock is called internally by the nonfairTryAcquire method as follows:
If the tryAcquire() method is tried again without success. First, addWaiter() method will be called to add the current thread to the waiting queue. The addWaiter method returns a Node node.
After returning to the node, acquireQueued(node,1) will try to update again.
If the update still cannot be updated, the thread will be suspended through parkAndCheckInterrupt.
ReentrantLock unlock method
Check out the release() method.
If the head of the queue is not empty and the waiting state of the head is not 0, the unparkSuccessor() method is called.
The unparkSuccessor() method is as follows:
Make the next of node traverse from back to front to get the first thread in the queue with waitStatus less than 0. Then continue the thread on the node.