Understanding multi-threading - java

I just have a question in regards to threads that run concurrently and the lock they have on an object. From what I understand is that the thread that calls the wait() method will go on a waiting list and allows another thread from a blocked list to take over the lock on and object(within synchronized code).
If this thread that now has the lock on the object calls the notify() method it wakes up the thread that called wait() and it is moved to the blocked list.
What happens to the thread that calls the notify() method. Does it still have a lock on the object or does it now go on a waiting list?
regards

Only one thread can hold the lock for an object. The wait() and notify() methods must be called while the thread holds the lock on the object you call these methods on; if they don't (for example, because you didn't synchronize on the object), you'll get an IllegalMonitorStateException.
When you call wait(), then the thread gives up the lock and goes on a waiting list (stops executing). When wait() returns, the thread will have obtained the lock again. However, the thread that calls notify() is still holding the lock, so the waiting thread will not resume before the notifying thread exits the synchronized block or method so that it releases the lock on the object.
By calling notify() the thread is not giving up the lock on the object.
A possible sequence of events would be:
Thread 1 goes into a synchronized block, obtaining the lock for the object
Thread 1 calls wait() on the object, giving up the lock, stops executing
Thread 2 goes into a synchronized block, obtaining the lock for the object
Thread 2 calls notify() on the object, but still holds the lock
Thread 1 is awakened and tries to obtain the lock, but it can't because Thread 2 still has it (so Thread 1 has to wait for the lock)
Thread 2 exits the synchronized block and releases the lock
Thread 1 can now obtain the lock and returns from wait()

The notifying thread still owns the lock. See doc section 17.14 (bottom of the page):
The notify method should be called for an object only when the current thread has already locked the object's lock. If the wait set for the object is not empty, then some arbitrarily chosen thread is removed from the wait set and re-enabled for thread scheduling. (Of course, that thread will not be able to proceed until the current thread relinquishes the object's lock.)

No, it will release the lock by leaving a synchronized block or returning from a synchronized method. It will not go back to the waiting list until calling wait() again.

Related

java: If notify() is always called before the lock release, how could a waiting threads acquire this same lock?

I think that I already know the answer to that question, however, I would like to read your opinions to make sure that I really understand how java thread's state machine (or diagram) works.
Imagine that Thread A runs the notify() just before return a given value:
public class baz{
// Thread B runs this:
public synchronized void bar(){
wait();
}
// Thread A runs this:
public synchronized int foo(){
notify();
return 11;
}
}
notify() will be called before Thread A releases the lock (that will occurs "after" the return 11; statement).
So, how could a Thread B, that is waiting for this lock (via wait() method), acquire the lock that is still held by Thread A?
Note that, when thread B is notified the lock has not yet been released by Thread A.
So what I think of this situation is the following:
After calling wait(), Thread B will change its state from Running to Waiting.
After receiving the notification (from Thread A notify() method), Thread B will return from wait(), change its state to Runnable and try to acquire the lock. Since the lock is not yet released by Thread A, Thread B will be blocked on the object's monitor and pass its state from Runnable to Blocked.
Eventually, after Thread A releases the lock, Thread B will acquire the lock and pass its state from Blocked to Running.
Is this right? What I want to understand with this question is what happens to a thread that returns from a wait() which is synchronized by an already acquired lock.
Yes, your explanation is correct.
When you call wait() on an object, the calling thread will be added to the object's wait set. When it is notify()ied, it will be removed from that wait set, and perform a lock action on the object (it's within a synchronized block on that object). That lock action will block the current thread until it is complete, ie. locked the object monitor.
This is the exact same behavior that two threads would have when trying to enter a synchronized block on the same object. The first thread to reach would lock the object monitor, completing the lock object immediately. The other thread blocks until its lock action is complete, ie. after the first thread unlocks the monitor.

doing lot of work after notify() will cause wait() become busy wait?

if i have the below piece of code
synchronized (this)
{
System.out.println("Waiting for return key.");
scanner.nextLine();
System.out.println("Return key pressed.");
notify();
Thread.sleep(5000);
}
After notify, I am calling sleep which means, I have notified the waiting thread but not relinquished the lock, what happens now.. After notifying the waiting thread would have been woken up but not able to acquire the lock, so from here on-wards, is it a busy wait? since we are not going to call notify again.
Same question goes with notify and notifyall, after one thread woken and acquired lock, is that all other thread waiting becomes busy wait?
wait() doesn't busy-wait, but it does "compete in the usual manner with other threads for the right to synchronize on the object" once notified.
A call to notify wakes up one thread that is currently waiting on the object's condition queue which then tries to reaquire the lock which is still held by the calling thread at that point of time. So the situation is comparable to a thread that wants to enter a synchronized block that is currently executed by another thread. The thread is not doing a busy-wait, it is just blocked until it can aquire the lock.
When the thread that called notify releases its lock, the other thread can be unblocked and continue to work.
The same is true for notifyAll, but it wakes up all threads that are waiting on the object's condition queue. As only one of them can acquire the lock, the others stay blocked until they get the lock - one after the other. This and because thread-awaking signals may happen spontaneous it is required to always call wait within a conditional loop:
synchronized (lockObject) {
// ...
while (!condition) {
lockObject.wait();
}
// object is now in desired state
}
See also: Java Concurrency in Practice, Chapter 14.2
A thread can wait on an object only when IT OWNS the object's monitor. Once the first thread notifies, the second thread wakes up but doesn't do anything. The only thing that happens here is that "The thread will be removed from the list of threads waiting on the object . It is left to the OS to schedule its execution. The OS might choose NOT to execute it for sometime. The thread doesn't busy-wait. It will just be in the set of threads which are waiting to be scheduled.
As #Holger points out, any thread which calls wait() releases the lock on the object. Once it is notified, it has to "compete" and reacquire the lock on the object. Reacquiring of lock doesn't happen when notify() is called by the thread which holds the lock. It happens when that thread exits its synchronized block.

what happens when a thread is interrupted while blocking on a wait()?

Considering the fact that wait() can only be called in a synchronized context which subsequently release the monitor until a notify/nofityAll has been called on the same object by another thread,
Assume Thread A is blocking on a wait() which results in Thread B acquiring the lock. Now if we interrupt Thread A, would control be transferred immediately to Thread A ? in which case, since the try catch block handling the InterrupException is within the synchronized context, and since only one Thread can hold the monitor at a time, what will happen to Thread B ? should it move to a blocked state until Thread A has finished execution ?
Thanks in Advance
Reading the documentation does in fact help:
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#wait%28long%29
Thus, when the thread is interrupted, it has to re-acquire the Object's monitor to restore the synchronisation state before the exception is thrown. The same holds for returning from the wait(long) call after the specified amount of time has elapsed.
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.
If the current thread is interrupted by another thread while it is
waiting, then an InterruptedException is thrown. This exception is not
thrown until the lock status of this object has been restored as
described above.
I believe that A will become runnable but will wait until it can acquire the lock before proceeding with the catch clause. It won't force B into a blocked state. The whole point of a synchronized block is that the thread holding the lock is guaranteed that no other thread can synchronize on the same lock until it gives up its lock; forcing B into a blocked state and letting A reacquire the lock would violate the very essence of synchronization.

Threading - wait()

The wait() method on an object can be called only in the synchronized context i.e. the current thread must have a lock on the object to invoke the wait() method. Now if a thread T1 has a lock on an object(obj) and invokes its wait method obj.wait() . How can other threads get lock on this object(obj) so that they can also call wait, which is already possessed T1 ?
wait releases the synchronized context. From the documentation:
The current thread must own this object's monitor. The thread releases
ownership of this monitor and waits until another thread notifies
threads waiting on this object's monitor to wake up (...)
You only need to be synchronized for the duration of calling the wait() method, not for the duration of the wait time.

java: wait(), notify() and synchronized blocks

I learned that calling an Object's wait() method will release the object monitor, if present.
But I have some questions regarding calling notify() on this object by another thread:
(when) will the waiting thread wake up, if another (a 3rd) thread owns the object monitor in the meanwhile?
will the waiting thread wake up, if a 3rd thread called wait() on this object?
is it possible to determine if a thread is waiting for notifying a particular object (java 1.4/java 5)
What's happening if wait() will be called in the finalize() method?
When you call wait() from a thread, that thread stop executing and it's added to the waitset of the object. When you call notify() from another thread, a random thread from the waitset is waked up, if you call notifyAll() all would be ready to execute.
When you call notify(), the thread is ready to run but it doesnt mean it will be executed inmediately so be careful.
It would wake up a thread from the waitset randomly.
Youd don't know which one will be waked up first, it doesn't follow any order.
Thread.getState()
You would produce deadlock.
notify will wake one thread waiting on the monitor. Unless and until the monitor is unowned, no thread waiting can run; wait() must be called in a synchronized block and so the lock must be held to continue running that block.
No guarantees. Call notifyAll to give all threads a chance to wake.
Dunno. You could have the thread set a variable saying it's waiting before it goes to sleep...
This is probably a bad idea. Can you come up with a situation where this is necessary?
That's why you have the notify() and notifyAll() methods. The former wakes up one thread waiting on the object, the latter wakes up all threads. A waiting thread will not wake up if wait() is called in another thread.
No.
It's only possible to call thread.holdsLock(obj) to see if a thread holds the monitor lock on a particular object.
Don't call wait() in a finalize method.
2: Not necessarily. notify() wakes up one of the waiting threads. It might be the original one or the third one.
3: Using thread.getState() you can find out if a thread is waiting for an object, but I don't know if you can always find out which object this is, exactly.

Categories