Threading - wait() - java

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.

Related

what is the behavior of java after returning to a synchronized block after notify on an object

I know that after we invoked a wait() on an object, the lock of that object will release to permit another thread to give that lock by a synchronized block and invoke notify().
before we entered the synchronized block that we have called wait() method, we acquire the lock and invoke the wait().
but after wait() the method release the lock.
now my question is after we invoke notify() in another thread, does the thread that is waiting on that object acquire the lock again.
below is a simple code for this:
Object obj = new Object();
synchronized (obj) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
afterWait();
}
is the lock of object acquire when jvm executes afterWait() method or not because it is also in a synchronized block.
In Java, monitors are implemented according to Mess' semantics. It implies that when current thread needs to wait, it releases the monitor and joins the other waiting threads to get the monitor once again. The written example is not safe, as wait should be in a loop with checking some condition to wait again, as Java does not guarantee that thread will be woken up only in the case of notify() or notifyAll() methods. It may work on your development environment but fail on another one. Also, notify() method does not guarantee that thread will wake up and get the lock as it may not get the signal, so it is safe to do notifyAll() to awake all threads waiting for the lock.
I am new to Stack Overflow, so I am not sure if my shared knowledge is straight to the question or no.
From the Javadoc of wait() (emphasis added):
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 either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

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.

how can sleep() method help other threads to execute, since it holds lock on that object itselt?

I have heared that sleep(timeInMilliseconds) method in java holds lock on object and goes to sleep for specified period of time. And I also read that it gives chance to other threads to execute in that sleeping period? How can the sleep() method help to other threads if it hols lock on object the other threads wants to use ?
The major difference between sleep() and wait() is that wait() releases the lock or monitor while sleep() doesn’t releases any lock or monitor while waiting. Wait is used for inter-thread communication while sleep is used to introduce pause on execution.
Thread.sleep() keeps the monitors it has acquired (if any).
Object.wait() sends the current thread (note that you apply it on the Object) into the “Not Runnable” state, like Thread.sleep(), but, again wait() is called on an Object, not on a Thread. Since the object is the lock and the thread-object is currently on a "non running state" the lock is released.
If the thread has not acquired any lock before sleeping, it wouldn't hold any lock. if it has, then YES, sleep() won't give chance to any other thread who is waiting to acquire lock on the object which the sleeping thread has acquired lock on.
So, sleep() just puts the thread to sleep for specified time, with all lock it has acquired (if acquired) in locked state.

Understanding multi-threading

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.

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