4

I have an object on thread A that is calling wait() while another object on thread B does some work then calls thread A's object's notify(). Thread A then performs some post-processing.

My problem is pretty straightforward:

synchronized(this)
{
    while(!flag)
    {
        try
        {
            wait();
            getLogger().info("No longer waiting");
        }
        catch (InterruptedException ie)
        {
            getLogger().info("Wait threw InterruptedException");
        }
    }
}

Results in an info message of "No longer waiting" instead of "Wait threw InterruptedException".

I am confused, because of this (http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#wait()):

Throws:

InterruptedException - if another thread interrupted the current thread before or while the current thread was waiting for a notification. The interrupted status of the current thread is cleared when this exception is thrown.

Why am I getting odd behavior?

Thanks.

Alex Weitz
  • 3,199
  • 4
  • 34
  • 57

4 Answers4

10

When a thread waits using wait(), he actually waits for notify(). So once notify() has been called by the other thread, this thread will continue, if you will call interrupt(), you would get the exception.

Also, from the documents you linked to:

Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object

notify releases the thread from the lock.

InterruptedException - if another thread interrupted the current thread before or while the current thread was waiting for a notification.

 

Alex Weitz
  • 3,199
  • 4
  • 34
  • 57
MByD
  • 135,866
  • 28
  • 264
  • 277
3

notify() does not make wait() throw InterruptedException. notify() let wait() continue the normal program flow.

alexcoco
  • 6,657
  • 6
  • 27
  • 39
PeterMmm
  • 24,152
  • 13
  • 73
  • 111
2

notify() is not an abnormal termintation for a thread that is wait()-ing. You'd get the exception if, for instance, the thread was terminated before notify() was called - not as a result of notify() being called. The thread hasn't been interrupted - it's been awoken.

Alex Weitz
  • 3,199
  • 4
  • 34
  • 57
James
  • 8,512
  • 1
  • 26
  • 28
0

Note that you have a bug in that code. Wait should always be invoked in a loop, and check a condition after waking up.

wait can be awaken by a spurious wakeup. See the javadoc wait()

Kaj
  • 10,862
  • 2
  • 33
  • 27
  • Given that we haven't seen any of the context of the code, you can't tell that it's got a bug. It's not in a synchronized block either, but I'm assuming there's one somewhere. – Jon Skeet May 19 '11 at 06:23
  • @Jon Skeet. The original post didn't have a loop with a condition, and the OP said "Thread A then performs some post-processing." The means that he wanted to wait till the other thread had completed processing. A wait without a condition to check is then a bug, due to spurious wakeups. The thread can be awaken without a notify and would then start post processing before the other thread had completed. – Kaj May 19 '11 at 06:56