Reentrantlock Source Analysis 1--get unfair lock and fair lock ()
The most common way: View Code
1, for Reentrantlock need to master the following Reentrantlock creation (Fair lock/non-fair lock) Lock: Lock () Unlock: Unlock ()
First of all, class structure: Reentrantlock-->lock nonfairsync/fairsync-->sync-->abstractqueuedsynchronizer--> Abstractownablesynchronizer Nonfairsync/fairsync-->sync is the three internal class of Reentrantlock node is an internal class of Abstractqueuedsynchronizer
Note: Above these four lines, corresponding relation: "Subclass"--> "Parent class"
2, the creation of Reentrantlock support Fair Lock (Advanced thread first execution) to support the unfair lock (the incoming thread may also be executed first)
Non-fair lock and unfair lock creation non-fair Lock: Reentrantlock () or Reentrantlock (false)
Final Reentrantlock lock = new Reentrantlock ();
Fair Lock: Reentrantlock (True)
Final Reentrantlock lock = new Reentrantlock (TRUE)
Unjust locks are used by default.
The source code is as follows:
Reentrantlock:view Code
There are three internal class Sync/nonfairsync/fairsync in the above source code, where only the definition of the class is listed, and the specific methods in these three classes are introduced at the first subsequent reference.
Sync/nonfairsync/fairsync class definition: View Code
3. Lock () of a non-fair lock ()
The specific use method:
Lock.lock ();
The following is a simplified version of this overall step, followed by a detailed source code and a detailed version of the steps in the Lock () method section of the source code.
simplified version of the steps: (The core of the non-fair lock)
Attempt to set state (number of locks) from 0 to 1 based on CAs
A, if the setting succeeds, set the thread that the current thread is an exclusive lock;
B, if the setting fails, the number of locks will be acquired again.
B1, if the lock number is 0, and then set the state (lock quantity) from 0 to 11 based on the CAS attempt, and if the setting succeeds, set the thread that the current thread is an exclusive lock;
B2, if the lock number is not 0 or the top attempt fails again, see if the current thread is already an exclusive lock thread, and if so, the current number of locks is +1; if not, the thread is encapsulated in a node and added to the wait queue. Waits to be awakened by its previous thread node.
Source code: (before introducing the source code, there is an overall impression of the steps to get the lock, which is the "simplified version of the steps" above)
3.1, Reentrantlock:lock () View Code
3.2, Nonfairsync:lock () View Code
Note: In this method, I list the detailed process for a thread to acquire a lock and look at the annotation myself.
The following is a list of several methods and related properties that are called in Nonfairsync:lock ().
3.2.1, Abstractqueuedsynchronizer: Lock Quantity state Property + related method: View Code
Note: State is a volatile type.
3.2.2, Abstractownablesynchronizer: Attribute +setexclusiveownerthread (Thread t) View Code
3.2.3, Abstractqueuedsynchronizer: attribute +acquire (int arg) View Code
Before introducing this method, let's say a whole structure of Abstractqueuedsynchronizer's internal class node, the source code is as follows: View code
Note: Here I give a full version of the node class, where some of the properties and methods are used in the mode of shared locks, and our reentrantlock here is an exclusive lock, just focus on the part of the exclusive lock that is involved (specifically commented)
3.3, the two methods used in the Abstractqueuedsynchronizer:acquire (int arg) method
3.3.1, Nonfairsync:tryacquire (int acquires) View Code
Syn:view Code
Note: This method completes the "simplified version of the steps" in the "A/B/B1" three steps, if the above request is not successful, it is necessary to execute the code below,
The following code, described in a sentence: after the request failed, the current thread chain to the tail and suspend, and then wait to be awakened . When you look at the code below the heart moji this sentence.
3.3.2, Abstractqueuedsynchronizer:addwaiter (Node mode) View Code
Abstractqueuedsynchronizer:enq (final node node) View Code
Note: Here is a complete method of team-taking, which looks at the relevant part of the annotation section of the annotation and Reentrantlock:lock ().
3.3.3, abstractqueuedsynchronizer:acquirequeued (Final node node, int arg) View Code
Abstractqueuedsynchronizer:shouldparkafterfailedacquire (node pred, node node) View Code
Abstractqueuedsynchronizer:view Code
The above is the entire process (lock ()) in which a thread acquires an unjust lock.
4. Lock of Fair locks ()
The exact usage is the same as the non fair lock
If you master the process of the unfair lock, then the process of mastering the fair lock will be very simple, only two different (finally speaking).
simplified version of the steps: (The core of the Fair lock)
Gets the number of locks at a time,
B1, if the number of locks is 0, if the current thread is the head node in the wait queue, the number of state (lock quantity) from 0 is set to 11 times based on the CAS attempt, and if the setting succeeds, set the thread that the current thread is an exclusive lock;
B2, if the number of locks is not 0 or if the front thread is not a header node in the queue or the top attempt fails, to see if the current thread is a thread that is already an exclusive lock, and if so, the current number of locks is +1; if not, the thread is encapsulated in a node and added to the wait queue. Waits to be awakened by its previous thread node.
Source code:
4.1, Reentrantlock:lock () View Code
4.2, Fairsync:lock () View Code
4.3, abstractqueuedsynchronizer:acquire (int arg) is the way to use a fair lock
4.3.1, fairsync:tryacquire (int acquires) View Code
Finally, if the request fails, the current thread chain is queued and suspended, then the wait is awakened, and the following code is the same as the unjust lock.
Conclusion: The comparison between fair lock and non fair lock Fairsync:lock () Less queue-jumping (that is, the process by which CAs tries to set state from 0 to 1 to obtain a lock) fairsync:tryacquire (int acquires) There is a lot of logic to determine whether the current thread is waiting for the queue header (in fact, it's less of a jump queue, but there is a CAS acquisition).
Finally, Reentrantlock is based on abstractqueuedsynchronizer implementation, Abstractqueuedsynchronizer can implement exclusive locks can also implement shared locks, Reentrantlock only uses the exclusive lock mode, which is a lot more code, logic is more complex, preferably in the process of reading, you can take a pen to draw the team and other data structure related to the diagram must remember the "simplified version of the steps", which is the whole of the unfair lock and fair lock core