what does WAKEUP really mean in the notify/notifyall context? - java

some comments here have confused me! I thought I knew this and god knows I've written a ton of MT code, but its been a while and so....
FWIK notify/notifyall
notify: one thread is selected from the waitset and moved to the entryset to acquire monitor lock
notifyall : all threads are "notified" -
are they all moved to the entryset ?
Does this mean that they will all reacquire the lock as the lock holder releases it ? no more notify necessary ?
-all answers are just rephrasing what I've read elsewhere. I understand that only one of them can acquire the lock etc., my question this: once a thread is notified, it gets to wait on the monitor. right ? so need not be notified again if the thread holding the lock calls notify

For a precise specification of what happens, refer to the JLS section 17.8.2.
When a thread performs a notifyAll on a lock object, all other threads that are currently waiting are removed from the lock's waitset; i.e. they become runable. Each one then tries to reacquire the lock, and when that succeeds it returns from the wait(...) call.
Of course, the threads only succeed in acquiring the lock one at a time, and there are no guarantees of fairness. But eventually, they will all have acquired the lock.

Notification of waiting threads occur when notifyAll is called. All the waiting threads are removed from the object's wait set. Only one of the thread in the wait set is selected, of which there is no guarantee as to which thread is selected
The langspec has a section on Thread Notification

When notifyAll is called, all threads waiting on that lock are woken up, and one of them acquires the lock. The rest goes back to wait.
This may sound like notifyAll is a waste of resources, but AFAIR there used to be special tricky cases when calling notify may wake up the wrong thread, which can not handle the situation, resulting in a deadlock. Therefore it was recommended to use notifyAll always.
Since Java5 it is rarely necessary to worry about things like this, because the new concurrency utilities almost always handle these tasks better than wait and notify*, rendering them almost obsolete. The typical use of wait and notify* is in blocking queues, and now we have several ready made implementations of these - such as LinkedBlockingQueue and PriorityBlockingQueue - available in the class library.

Related

What if notifyAll is called at the start of critical section

What if notifyAll is called at the start of critical section where lock is not released and released at the end of cs(critical section). What will happen to waiting threads?
Do the notifyAll will get heard by all threads and all thread will try to get lock and get unsuccessful(since notify/notifyAll do not release lock) and keep on trying until they get the lock?
So, what difference it makes to call notify at the start of critical section or at the end ?why it is recommended to call notifyAll at the end of cs?
When you call notifyAll() all waiting threads are reactivated and try to acquire the lock on the object on which you called notifyAll().
IMHO the correctness of your code is not sacrificed - no other thread can acquire the lock as long as it is held by the current thread (the one calling notifyAll()).
But the performance will suffer - waking up threads takes processor resources, having them try to acquire the lock takes processor resources, waiting for the release of the lock takes processor resources.
Often the advice to call notifyAll() at the end of a critical section is fulfilled trivially because your thread is doing some processing in a critical section and at the end of that processing it notices that it should notify waiting threads that they can continue. In that case notifying other threads that they can continue before being sure that this is really the case doesn't make any sense.

What does it mean by waiting on object monitor [duplicate]

Someone at work just asked for the reasoning behind having to wrap a wait inside a synchronized.
Honestly I can't see the reasoning. I understand what the javadocs say--that the thread needs to be the owner of the object's monitor, but why? What problems does it prevent? (And if it's actually necessary, why can't the wait method get the monitor itself?)
I'm looking for a fairly in-depth why or maybe a reference to an article. I couldn't find one in a quick google.
Oh, also, how does thread.sleep compare?
edit: Great set of answers--I really wish I could select more than one because they all helped me understand what was going on.
Lots of good answers here already. But just want to mention here that the other MUST DO when using wait() is to do it in a loop dependent on the condition you are waiting for in case you are seeing spurious wakeups, which in my experience do happen.
To wait for some other thread to change a condition to true and notify:
synchronized(o) {
while(! checkCondition()) {
o.wait();
}
}
Of course, these days, I'd recommend just using the new Condition object as it is clearer and has more features (like allowing multiple conditions per lock, being able to check wait queue length, more flexible schedule/interrupt, etc).
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
lock.lock();
try {
while (! checkCondition()) {
condition.await();
}
} finally {
lock.unlock();
}
}
If the object does not own the object monitor when it calls Object.wait(), it will not be able to access the object to setup a notify listener until the the monitor is released. Instead, it will be treated as a thread attempting to access a method on a synchronized object.
Or to put it another way, there is no difference between:
public void doStuffOnThisObject()
and the following method:
public void wait()
Both methods will be blocked until the object monitor is released. This is a feature in Java to prevent the state of an object from being updated by more than one thread. It simply has unintended consequences on the wait() method.
Presumably, the wait() method is not synchronized because that could create situations where the Thread has multiple locks on the object. (See Java Language Specifications/Locking for more info on this.) Multiple locks are a problem because the wait() method will only undo one lock. If the method were synchronized, it would guarantee that only the method's lock would be undone while still leaving a potential outer lock undone. This would create a deadlock condition in the code.
To answer your question on Thread.sleep(), Thread.sleep() does not guarantee that whatever condition you are waiting on has been met. Using Object.wait() and Object.notify() allows a programmer to manually implement blocking. The threads will unblock once a notify is sent that a condition has been met. e.g. A read from disk has finished and data can be processed by the thread. Thread.sleep() would require the programmer to poll if the condition has been met, then fall back to sleep if it has not.
It needs to own the monitor, since the purpose of the wait() is to release the monitor and let other threads obtain the monitor to do processing of their own. The purpose of these methods (wait/notify) is to coordinate access to synchronized code blocks between two threads that require each other to perform some functionality. It is not simply a matter of making sure access to a data structure is threadsafe, but to coordinate events between multiple threads.
A classic example would be a producer/consumer case where one thread pushes data to a queue, and another thread consumes the data. The consuming thread would always require the monitor to access the queue, but would release the monitor once the queue is empty. The producer thread would then only get access to write to the thread when the consumer is no longer processing. It would notify the consumer thread once it has pushed more data into the queue, so it can regain the monitor and access the queue again.
Wait gives up the monitor, so you must have it to give it up. Notify must have the monitor as well.
The main reason why you want to do this is to ensure that you have the monitor when you come back from wait() -- typically, you are using the wait/notify protocol to protect some shared resource and you want it to be safe to touch it when wait returns. The same with notify -- usually you are changing something and then calling notify() -- you want to have the monitor, make changes, and call notify().
If you made a function like this:
public void synchWait() {
syncronized { wait(); }
}
You would not have the monitor when wait returned -- you could get it, but you might not get it next.
Here's my understanding on why the restriction is actually a requirement. I'm basing this on a C++ monitor implementation I made a while back by combining a mutex and a condition variable.
In a mutex+condition_variable=monitor system, the wait call sets the condition variable into a wait state and releases the mutex. The condition variable is shared state, so it needs to be locked to avoid race conditions between threads that want to wait and threads that want to notify. Instead of introducing yet another mutex to lock its state, the existing mutex is used. In Java, the mutex is correctly locked when the about-to-wait thread owns the monitor.
Mostly wait is done if there is a condition say a queue is empty.
If(queue is empty)
queue.wait();
Let us assume the queue is empty.
In case if the current thread pre-empts after checking the queue, then if another
thread adds few elements to queue, the current thread will not know and will go for wait
state. Thats wrong.
So we should have something like
Synchornized(queue)
{
if(queue is empty)
queue.wait();
}
Now let us consider what if they made wait itself as synchronized. As already mentioned in one of the comments, it releases only one lock. That means if wait() was synchronized in the above code only one lock would have been released. Implies that current thread will go for wait with the lock for the queue.

Why do we need notify() for inter thread communication

From the JAVA docs for Object notify()
The awakened thread will not be able to proceed until the current
thread relinquishes the lock on this object.
This means that unless the Thread which notifes, its synchronized block is complete and it releases the lock, the waiting thread cannot proceed. If that's the case then whats the point of having notify() if the sync block is going to be executed anyway? What's the actual use of notify() if it doesn't wake up the waiting thread and let it do its job?
Good question. Will point you to take a look at the Thread State Class.
A thread that calls the Object.notify method enables a thread that previously called Object.wait is now enabled to be scheduled by the thread scheduler. In parlance, the thread that was waiting is now "runnable". Although it is "runnable", it is not "running".
It can only continue running when the thread invoking notify releases the lock - one way is when it exits out of the synchronized block.
There are a lot of schematics on the web on the Thread States. Some of them are completely incorrect or confusing since they introduce terminology not in the official docs. Here is one that makes sense to me.
Strictly speaking, we don't: we could have the waiting thread run a loop where it re-acquires the lock, checks the condition, and sleeps for a short amount of time. But using wait() and notify() is much more efficient, because then the waiting thread doesn't keep waking up and tying up CPU (and tying up the lock).
notify() and notifyAll() are used to wake up thread(s) that called wait() on the same object on which notify() or notifyAll() is called.
Without call to notify() those "waiting" threads will wait forever (although JVM spec says that threads may sometime wake up without call to notify).
Also because call to notify() doesn't releases the lock associated with the object itself that call usually is the last statement in a synchronized block.
So notify() is used together with wait() and not by itself.
Usually the use case is like the following (blocking queue with limited size).
Method that adds element to queue (some pseudo code)
synchronized(lockObject) {
if (size < LIMIT) {
addElement();
lockObject.notifyAll(); //notifying threads that are waiting to get element from empty queue
} else {
lockObject.wait(); // waiting for other thread to get element from queue and make room for new element
}
}
Method that gets element
synchronized(lockObject) {
if (size > 0) {
getElement();
lockObject.notifyAll(); // notify threads that there is a room for new element
} else {
lockObject.wait(); // waiting for other thread to put element into the queue
}
}
Also calling lockObject.wait() releases lock on lockObject. More details regarding that could be found here: Java : Does wait() release lock from synchronized block
Notifying is what wakes up a thread that is waiting. If you remove the notify then waiting threads stay waiting (barring spurious wakeups but let’s not go there for now).
(Interrupting wakes up the thread but the guidance is to use it for cancellation only. Interruption targets a specific thread, where notifying lets the scheduler decide which threads are affected.)
When a thread calls wait it has to have the lock, then the wait method lets go of the lock.
When a thread calls notify it has to have the lock.
As a practical matter the notify can’t take effect on any waiting thread until the notifying thread relinquishes the lock. The first thing the notified thread is going to need to do anyway is to try to acquire the lock. All the passage you're quoting is trying to say is that the wakeup doesn't occur instantaneously when a thread calls notify.
So what happens here is that the notifying thread lets go of the lock and sends the notify to the scheduler, the scheduler decides which thread to notify, then the notified thread wakes up and contends for the lock in order to leave the wait method.
Imagine if you need a thread to wait for another thread to do something that it may or may not even currently be actively working on. For example, a thread that's waiting for a job to do may need to wait until another thread has put a job on the list of jobs it should do if that list is empty. How would you do this?
You can't just use some form of mutual exclusion. There may be long periods of time when there's no work to do and not thread holds any lock on the queue. There may just not be any work to do right now. The thread that does work needs to wait, without holding any lock, until another thread has given it some work to do.
So somewhere, there's a thread that does something like this:
Acquire the lock that protects some shared state that another thread might be waiting for a change to. (In this case, the job queue.)
Change the shared state to reflect the fact that the thing a thread might need to wait for has happened. (That is, put a job on the queue.)
Release the lock and let any waiting thread(s) know that the thing has happened.
So what could our code to wait look like? Perhaps:
Acquire the lock that protects the shared state.
Check whether we need to wait or not. (Is there a job on the queue?)
If we need to wait, wait. (If not, wait for a job to be placed on the queue.)
...
Oops, we have a problem. The thing we're waiting for can't happen because we hold the lock. No other thread can change the shared state. (Our thread to put a job on the queue can't touch the queue until we release the lock we acquired in step 1.)
Let's try it again:
Acquire the lock that protects the shared state.
Check whether we need to wait or not. (Is there a job on the queue?)
If we don't need to wait, exit this algorithm. (If there's a job, take it off the queue, release the lock, and do it.)
Release the lock. (So another thread can put a job on the queue.)
Wait for the thing to happen.
...
Oops, we have another problem. What if the thing we're waiting for happens after step 4 but before step 5. Since the lock has been released, the thing we're waiting for can happen. We can't check again because we don't hold the lock. How can we ensure we don't wait for something that has already happened, which may mean waiting forever?
To solve this, we need an atomic "unlock and wait" operation. That's what wait does. And we also need some operation that can end this wait that can be called by the thread that changed the shared state so that we no longer need to wait. That's what notify does.

while(condition) { Object.wait() } idiom

I know, that we use this idiom for waiting for notification to handle spurious wakeups:
synchronized (obj) {
while(somecond)
obj.wait();
}
If a spurious wake up arises, we'll just check the state and return back to waiting.
But, consider the situation:
We begin waiting, and obj.wait() releases lock on obj.
Waiting thread is spuriously notified by OS
We return to checking condition (with obj lock released due to wait)
obj.notify() is called right in that moment.
Yes, condition checking is extremely fast and chances, that we can be in condition checking and not in obj.wait(), are negligibly small. In that case we can loose obj.notify() call.
Am I misunderstanding something, or we really can loose notification using this pattern?
Another thread needs the lock on obj to be able to call obj.notify(). And it can't have it if your thread is in the while loop not waiting, since your thread also needs the lock on obj to be in the while loop.
The call to obj.wait() will not return until an obj.notify() has been called. However, you might fail to respond to an obj.notify() if another thread is also waiting and the system decides to notify that thread instead. If you want to avoid that, you can use obj.notifyAll(). If only one thread is waiting, you cannot lose the notification with this pattern.
Note that the other thread cannot call obj.notify() unless it holds the lock. If this thread is busy checking the condition, then it has the lock and the other thread cannot issue a notification. The synchronized block is essential to the operation.
In the case you present, Thread A is evaluating the condition, and Thread B is calling notify such that Thread A misses the notify call
This scenario would not be possible for that notify to be called since it must own the lock that Thread A is using in the synchronized block - only one thread can own that lock at once. See the javadoc on notify for more details.
The modifications to the state we are checking should be made, while the lock on obj is held by whomever calls obj.notify() afterwards. So, assuming we are currently checking the state, we are also holding the lock on obj.
If we are getting a spurious wake up, and the state has not changed, no one should have called obj.notify(). If the state has changed and we we miss a obj.notify(), it does not matter: For all intends, a spurious wake up and a wakeup by a call to obj.notifiy() have the same effect now.
The lesson is, that the state we are checking for should only be changed, while whoever is changing the state holds a lock on the object we are waiting on.
Since most of the answers insist on the impossibility of the scenario it’s worth to adjust that:
It is always possible to have a call to notify without a matching waiting thread. This might happen when the notifying thread invokes notify before the other thread even entered the entire synchronized block. The notify method might even have been called multiple times before any thread enters a synchronized block to wait and the wait-notify mechanism won’t count these.
So you have to handle the case that you missed a notify, e.g. by checking the condition within the synchronized block before calling wait. But by doing so you add the possibility to process and reset the condition while the matching notify is indeed pending.
Therefore you must be always aware of the possibilities that either
you may have missed one or more notify invocations
you may receive an obsolete notify
That’s why the correct handling loop likes like that
synchronized(obj) {
while(somecond)
obj.wait();
}
From an application’s point of view there is no difference between outdated pending notifys and the spurious wakeups generated by the JVM/OS without associated notify invocations. That’s why there is no attempt to prevent spurious wakeups by the JVM. The effort would be wasted as the logic wouldn’t change.

Does the Java JVM guarantee the correct "wait" will be notified when calling "notify"?

According to a colleague, JVM does not guarantee that when calling "notify" on an object, the correct "wait" will be notified at that time. He says there can be a case when a previous notify which is not valid anymore is delivered at an invalid time.
Is this true? If so, how/why is this, and what use is the wait/notify mechanism if you cannot assume something as basic as this will work?
For java.lang.Object.notify, The Javadoc says:
Wakes up a single thread that is waiting on this object's monitor. If
any threads are waiting on this object, one of them is chosen to be
awakened. The choice is arbitrary and occurs at the discretion of the
implementation. A thread waits on an object's monitor by calling one
of the wait methods.
Here is a pattern to wait for a particular condition:
synchronized( lock ) {
while( conditionEvaluation( data )) {
lock.wait();
}
}
The counterpart should use java.lang.Object.notifyAll() to ensure the vivacity of the application. Even if today, it's only one waiter, after many evolutions of the software, it may be several waiters in the future, so notifyAll() is more robust than notify().
Each object that waits on an intrinsic lock will enter the lock's wait set. When you invoke notify on the lock object, one of the threads in its wait set will be chosen to resume work. The only guarantee that the JVM offers is that the waiting threads will be eventually notified. One of the main reasons for this non-deterministic behavior is the way suspended threads are chosen to run by the JVM, which is arbitrary. In addition however, locks in java implement a non-fair locking policy which permits thread barging. This simply means that it is permissible for new lock requests to jump ahead of the lock's wait set, it the lock is available at the time of the request. The justification behind this is that given substantial contention, there might be some (potentially significant) delay before choosing and resuming a suspended thread in the wait set and the time it actually runs. Any incoming lock request from a thread could therefore utilize this time delay to immediately run, in the hope that it will have released the lock by the time the resumed thread is ready to run. For example consider the following sequence of events:
Thread A that previously has acquired monitor X calls notify()
Thread B waiting on monitor X has chosen to be suspended (arbitrarily).
Thread C tries to acquire monitor X, sees that it is available and acquires it.
Thread C runs (despite thread B is currently in the process of being resumed)
Thread C finishes execution and releases monitor X, just before thread B is actually run.
Thread B is ready to run so it acquires the lock and starts execution.
It should be evident that between step 2 and 6 there exists some time interval where no threads are actually using the lock. Thread C barges in and utilizes the time interval as an optimization. The downside of this of course is the risk of not releasing the lock at the time thread B is ready to run, which at that time thread B will notice that the lock is unavailable and will enter the wait set again. Statistically however it can be proven that non-fair locking offers better performance in most situations.
As an aside note, you could use fair locks where waiting threads are resumed in the order they acquired the lock, but in practice this offers worse performance. Read more about this here: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReentrantLock.html
I hope this answers your question.
No it's not true. When a thread invokes notify, one waiting thread is awakened (if such a thread exists, otherwise notification is lost). Probably your colleague had in mind "spurious notify", which can awake a thread when in fact no other thread invoked notify or notifyAll. To filter "spurious notify", each notify invocation should accompanied with some change in monitored object state, and the waiting threads should check that state:
synchronized void up() {
counter++;
notify();
}
synchronized void down() {
while (counter==0) {
wait();
}
counter--;
}
Note checking state in down() is done before call to wait(), as it could be changed before the invocation and the notification is lost. In other words, the real information is passed with object's state, and wait/notify only help to avoid polling. Never rely on notifications without changing an object's state.

Categories

Resources