Reputation: 23419
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 ?
Upvotes: 14
Views: 3178
Reputation: 11
// 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?
Upvotes: 0
Reputation: 96395
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 thewait
method was invoked. ThreadT
then returns from the invocation of thewait
method. Thus, on return from thewait
method, the synchronization state of the object and of threadT
is exactly as it was when thewait
method was invoked.
Upvotes: 9
Reputation: 3624
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(...).
Upvotes: 0
Reputation: 691735
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.
Upvotes: 7