简体   繁体   中英

How does wait() get the Lock back in Java

It is an advocated paradigm that wait() should be invoked inside a while loop inside a synchronized block.

My question is how does the waiting() thread get the lock back ?

// Thread 1
    synchronized (mon) {
     while (!condition) 
          mon.wait();

    // Do something
    }

//Thread 2
    synchronized (mon) {//set condition appropriately
            mon.notify();
    }

Consider the thread 1 runs first and starts waiting for the condition. It releases the lock and the thread 2 obtains the lock sets the condition and notifies thread 1. Now thread 1 gets the lock, checks the condition and starts executing "do something".

My question is when Thread 1 is notified it starts execution from the while condition, the line of code which had Synchronized(mon) is never executed again then how does thread 1 acquire the lock ? What are the internal dynamics that give the lock back to Thread 1 ?

When Thread1 is notified the thread has to acquire the lock before it can exit the wait method, see the java doc for Object#wait:

The thread T is then removed from the wait set for this object and re-enabled for thread scheduling. It then competes in the usual manner with other threads for the right to synchronize on the object; once it has gained control of the object, all its synchronization claims on the object are restored to the status quo ante - that is, to the situation as of the time that the wait method was invoked. Thread T then returns from the invocation of the wait method. Thus, on return from the wait method, the synchronization state of the object and of thread T is exactly as it was when the wait method was invoked.

synchronized(mon) is not an expression that has to be executed.

It's a syntax element in the source code that tells the compiler (and then the runtime) that the wrapped section of the code must only be executed after the lock associated with mon has been acquired by the current thread, even if you don't "come from" the line of code before the synchronized block.

wait() releases the lock, and must reacquire it before returning.

After Thread 1 is notified, it got the lock immediately and start to run //Do something .

When Thread 1 wait, it just release the lock temporarily, and when the thread is notified, it can get the lock again and needn't run synchronized(...).

// Thread 1
 synchronized (mon) {
 Systemout.println("I am invoked!");
 while (!condition) 
      mon.wait();

// Do something
}

//Thread 2
synchronized (mon) {//set condition appropriately
        mon.notify();
}

In the original scenario: Consider the thread 1 runs first and starts waiting for the condition. It releases the lock and the thread 2 obtains the lock sets the condition and notifies thread 1. Now thread 1 gets the lock, checks the condition and starts executing "do something".

If my understand the following correctly:

The thread T is then removed from the wait set for this object and re-enabled for thread scheduling. It then competes in the usual manner with other threads for the right to synchronize on the object; once it has gained control of the object, all its synchronization claims on the object are restored to the status quo ante - that is, to the situation as of the time that the wait method was invoked. Thread T then returns from the invocation of the wait method. Thus, on return from the wait method, the synchronization state of the object and of thread T is exactly as it was when the wait method was invoked.

the line Systemout.println("I am invoked!"); will not be executed, as "Thus, on return from the wait method, the synchronization state of the object and of thread T is exactly as it was when the wait method was invoked."

Am I right?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM