[Diagram Java] Reentrantlock Re-entry lock

Source: Internet
Author: User

Graphical ReentrantLock0. Demo

I first give a demo, so that everyone can according to the code I gave, debugging side to see the source. Or that sentence: Pay attention to "my", I renamed the Reentrantlock class for "Myreentrantlock" class, "Lock" class renamed to "MyLock" class. When you paste my code, the corresponding "my" are removed, otherwise it will compile error OH.

Import Java.util.scanner;import Java.util.function.supplier;public class Main {static final Scanner Scanner = new Scan    NER (system.in);    static volatile String cmd = "";    private static Myreentrantlock lock = new Myreentrantlock (true);            public static void Main (string[] args) {for (String name:new string[]{"1", "2", "3", "4", "5", "6"})        New Thread ((), Func ((), lock, Name). Start ();        while (Scanner.hasnext ()) {cmd = Scanner.nextline (); }} public static void Func (Supplier<mylock> mylocksupplier, String name) {blockuntilequals (() c        MD, "lock" + name);        Mylocksupplier.get (). Lock ();        SYSTEM.OUT.PRINTLN ("acquired" + name + "number lock");        Blockuntilequals ((), cmd, "unlock" + name);        Mylocksupplier.get (). Unlock ();    System.out.println ("released" + name + "number lock"); } private static void Blockuntilequals (Supplier<string> cmdsupplier, final String expect) {while (!cmdsup PliEr.get (). Equals (expect)) QuietSleep (1000);        } private static void QuietSleep (int mills) {try {thread.sleep (Mills);        } catch (Interruptedexception e) {e.printstacktrace (); }    }}

Use the example below. First thread 1 applied for a lock, which successfully applied. Then thread 2 requested the lock, did not apply to it, and entered the waiting queue. Thread 3 and Thread 4 also request a failure to enter into the wait queue.

Then the lock 1 is released, and then the lock 2 is acquired to the lock. Then release the lock 2, lock 3 to get to the lock ...  Then is the lock 4. This is probably the use. Using my Code with debug, you can clearly debug the execution flow of the code.

2. Start Diagram Reentrantlock

There is only one sync member variable in a reentrantlock () instance.

Suppose we create a fair lock, then sync is an instance of the Fairsync class.

There are four member variables in the sync instance.

respectively, say:

1. State-Lock counter

2. Exclusiveownerthread-Lock Holding thread

3. Head-the first node of the ' Wait queue '.

4. Tail-point to the last element of ' waiting queue '

The lock is now idle.

When thread 1 requests a lock, the state is set to 1. Then point the exclusiveownerthread of the lock to itself (thread 1). That's a lock. Other threads can no longer acquire locks. Only wait for thread 1 to be released.

What if thread 1 performs the lock () method on this one?

Then the lock is re-entered, which means that the thread enters (acquires) the lock again, which makes the state+1.

and re-enter it? Then add another 1 ....

How many times can I re-enter it? Can be re-entered until the shaping int overflows ...

Next, Thread 1 has not released the lock yet, thread 2 wants to get the lock. So what's going to happen:

Encapsulates thread 2 as a node of type nodes. Then I'm going to put this node in the ' Waiting queue '.

This time ' Wait queue ' will be built, because this time only need ' wait queue ', this is called lazy initialization.

At this point, the ' Waiting queue ' head node is generated. Then the ' Waiting queue ' tail also points to head.

Head or tail is not NULL, indicating that the ' waiting queue ' was created.

Head==tail said, ' Wait queue ' is empty, there is no ' active element ' inside.

The ' Waiting queue ' is there. Thread 2 corresponds to node. Just put this node at the end of the team.

First let tail point to thread 2 corresponding to node.

Then each of the two node's precursors and successors were maintained. (See purple arrows below)

The node for thread 2 has been inserted at the end of the ' wait queue ', so that thread 1 corresponds to node waitstate equal to-1

Then thread 2 will be able to hang up at peace of mind. When thread 1 completely releases the lock, it wakes up thread 2.

Why is it ' completely free '? Because the state of the lock is now equal to 3. A thread 1 unlock () is required to release 3 locks before it is completely released.

Next, Thread 1 has not released the lock, (thread 2 also does not turn to lock). Thread 3 wants to get the lock. So what's going to happen:

The first node that corresponds to thread 3 is created.

Then let the tail pointer tail point to the newest node.

Then maintain the precursors and successors (purple arrows) to maintain the doubly linked list.

The next step is to waitstatus the new node's predecessor node =-1.

-1 indicates that there is a next node waiting to be awakened.

Then thread 3 will be able to hang up with peace of mind.

When thread 2 grabs the lock, it will wake up thread 3 after the release is exhausted.

Let's make thread 1 unlock () once.

State minus 1.

At this point, the lock is not released or is held by thread 1.

Let's get the thread 1 unlock () once more.

State minus 1. But still greater than 0.

At this point, the lock is not released or is held by thread 1.

Let's get the thread 1 unlock () once more.

State minus 1. This time the state is equal to 0. Indicates that the lock was completely released.

The Exclusiveownerthread is also set to NULL, which indicates that the current lock is not held by any thread.

Ready to wake up next, the first element of ' waiting queue ' (thread 2)

Thread 2 is awakened

Then the state of the lock is placed in order to 1.

The exclusiveownerthread of the lock points to thread 2. Indicates that the current lock is held by thread 2.

Now that thread 1 has completely released the lock. Then change the thread to the first node of the ' Wait queue '.

So at this point, the meaning of the head node is the node node of the thread that currently holds the lock.

Then disconnect the corresponding precursor and successor, so that thread 1 corresponds to node completely out of the ' waiting queue '.

By this, after thread 1 is released, thread 2 acquires the lock and the steps are all done.

Next, let's get thread 2 to release the lock.

State minus 1 equals 0.

So the lock was completely released. The exclusiveownerthread is set to null.

Then the waitstatus was changed back to 0. Thread 2 corresponding node will leave the ' waiting queue ' immediately.

Thread 3 is awakened.

Let state=1, and put the exclusiveownerthread of the lock point to yourself. Represents the thread 3 itself exclusive of this lock.

Modify the head pointer, and disconnect the corresponding precursor and subsequent links, so that thread 2 corresponding node leaves the ' waiting queue ' completely

Finally, let's get thread 3 to release the lock.

State is zeroed.

Exclusiveownerthread empty.

Lock Idle.

and head and tail still point to the original node. The head node that waits for the queue later does not need to be reinitialized.

[Diagram Java] Reentrantlock Re-entry lock

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.