Graphical Condition0. 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.concurrent.locks.condition;import Java.util.function.supplier;public Class Conditiontest {static final Scanner Scanner = new Scanner (system.in); static volatile String cmd = ""; private static Myreentrantlock lock = new Myreentrantlock (true); private static Condition Condition = Lock.newcondition (); public static void Main (string[] args) {for (String name:new string[]{"W1", "W2", "W3", "W4", "W5", "W6"}) New Thread ((), Func ((), lock, Name). Start (); New Thread ((), Signalone ((), lock, "s"). Start (); while (Scanner.hasnext ()) {cmd = Scanner.nextline (); }} public static void Func (Supplier<mylock> mylocksupplier, String name) {blockuntilequals (() c MD, name); Mylocksupplier.get (). Lock (); SYSTEM.OUT.PRINTLN (name + "blocking wait ..."); try {condition.await (); } catch (Interruptedexception e) {E. Printstacktrace (); } System.out.println ("released" + name); Mylocksupplier.get (). Unlock (); public static void Signalone (Supplier<mylock> mylocksupplier, String name) {while (true) {b Lockuntilequals ((), CMD, name); Mylocksupplier.get (). Lock (); Condition.signal (); SYSTEM.OUT.PRINTLN ("Notification wakes up a wait ..."); Mylocksupplier.get (). Unlock (); }} private static void Blockuntilequals (Supplier<string> cmdsupplier, final String expect) {while (!c Mdsupplier.get (). Equals (expect)) QuietSleep (1000); Clearcmd (); } private static void QuietSleep (int mills) {try {thread.sleep (Mills); } catch (Interruptedexception e) {e.printstacktrace (); }} private static void Clearcmd () {cmd = ""; }}
Use the example below.
Enter W1 first to have thread 1 execute await (). Then enter W2 to have thread 2 execute await (). Then enter W3 to have thread 3 execute await ().
Next enter 3 times s, did not enter the S, and press ENTER, will signal notify an await wait.
1. Start diagram condition
If you want to use Reentrantlock's condition, then you must first have a reentrantlock lock.
Instantiate a lock with only one member variable sync in Reentrantlock.
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 '
We then instantiate a condition.
When we entered W1, the first thread applied for the lock and the application was successful.
It then executes to the await () method.
Wrap thread 1 as node, and then waitstate to-2. -The meaning of 2 is condition.
The first step inside the await () method is to insert the current thread (thread 1) into the ' conditional queue '.
It then starts releasing the lock on the current thread (thread 1), and it is completely released, releasing all the re-entry times at once, which means that state equals 0 directly.
The lock is released, then thread 1 is suspended.
Then let thread 2 await. (That is, the previous demo program has entered W2 in the console.)
Thread 2 takes the lock before performing an await () of course.
Because of this time, the lock is idle. So thread 2 succeeded in acquiring the lock. The shaded part of the light Orange is the content of the change:
After the lock is acquired, thread 2 should perform an await ():
For example, wrapping a thread as node and then inserting it into the ' conditional team ' is just the first step of the await () method.
The next action is to completely release the lock on thread 2 and then suspend the thread.
If we enter "s" in the console of the demo program at this time, the thread s will be asked to apply for the lock, and the signal will be executed after the application is successful.
The first is thread s to apply for lock success:
After the thread S has successfully acquired the lock, it is time to execute signal ().
First break out the first node in the ' Conditional queue ':
Then change the waitstate from-2 to 0:
The next thing to do is to detach node from the ' Conditional queue ' (which is the node of thread 1), and end up in the ' Waiting queue '.
But the ' Wait queue ' is not initialized at this time, so the ' wait queue ' is initialized before being inserted into ' wait queue '. See:
' Wait queue ' is initialized. Next is the thread 1 corresponding to the node, the tail into the ' Waiting queue ':
Then the waitstate of the predecessor of the node that is currently in the wake is set to-1. 1 indicates that the next node waits to be awakened.
Next is the thread s that executes to unlock (). The lock is then released and then the first thread in the wait queue is awakened.
So we're done. Signal ()
A signal command moves an await thread from the ' conditional queue ' to the ' waiting queue '. After the wait queue, the rest is the same as the "lock unlock, Wake next Execution" step.
I think the await method is to plug the thread tail into the ' conditional queue '. The signal () method is to insert the end of the first element in the conditional queue into the ' waiting queue '.
So I don't think I need to analyze it.
It may be that I take it for granted, and then add it if something goes wrong.
[Diagram Java]condition