Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If wait() throws an InterruptedException, does the thread wait until it acquires the object's monitor?

For example:

public synchronized Object get() {
    while (result == null) {
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
            // Do we own the monitor of this object?
        }
    }
    return result;
}

When e.printStackTrace() executes, are we guaranteed to own the object's monitor?

The reference says that when wait() returns after a notify() or notifyAll() call, the thread waits until it acquires the object's monitor. But what about the case when wait() throws an exception?

like image 460
fhucho Avatar asked May 02 '18 13:05

fhucho


People also ask

Why wait method throws InterruptedException?

An InterruptedException is thrown when a thread is interrupted while it's waiting, sleeping, or otherwise occupied. In other words, some code has called the interrupt() method on our thread. It's a checked exception, and many blocking operations in Java can throw it.

What happens when a thread executes wait ()?

So, when wait() method is called by a thread, then it gives up the lock on that resource and goes to sleep until some other thread enters the same monitor and invokes the notify() or notifyAll() method. Calling notify() wakes only one thread and calling notifyAll() wakes up all the threads on the same object.

What happens InterruptedException?

Class InterruptedException. Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity. Occasionally a method may wish to test whether the current thread has been interrupted, and if so, to immediately throw this exception.

Can a thread wait on a monitor?

Monitors. Monitor is a synchronization construct that allows threads to have both mutual exclusion (using locks) and cooperation i.e. the ability to make threads wait for certain condition to be true (using wait-set).


2 Answers

By the time wait returns (including the case where it throws InterruptedException) the thread has to have the monitor, otherwise it can't be executing in that synchronized method. The thread has to acquire the monitor before it can leave the wait method. Then once it's out of the wait method the thread has the monitor, and releases it when the thread leaves the method.

It's better here to throw the InterruptedException to the caller instead of eating it. Your goal here is to get out quickly and let the caller know an interruption happened so it can wrap things up. Eating it here also seems to mean you go back through the while loop again. Interruption is used by java.util.concurrent to implement cancellation, especially if you make use of java.util.concurrent tools it makes sense to write code that is compatible with them.

like image 64
Nathan Hughes Avatar answered Oct 13 '22 16:10

Nathan Hughes


Yes. In fact, this InterruptedException is thrown after re-acquiring the monitor.

See wait in jls:

Let thread t be the thread executing the wait method on object m, and let n be the number of lock actions by t on m that have not been matched by unlock actions. One of the following actions occurs:

  • If n is zero (i.e., thread t does not already possess the lock for target m), then an IllegalMonitorStateException is thrown.

  • If this is a timed wait and the nanosecs argument is not in the range of 0-999999 or the millisecs argument is negative, then an IllegalArgumentException is thrown.

  • If thread t is interrupted, then an InterruptedException is thrown and t's interruption status is set to false.

  • Otherwise, the following sequence occurs:

    1. Thread t is added to the wait set of object m, and performs n unlock actions on m.

    2. Thread t does not execute any further instructions until it has been removed from m's wait set. The thread may be removed from the wait set due to any one of the following actions, and will resume sometime afterward:

      • A notify action being performed on m in which t is selected for removal from the wait set.

      • A notifyAll action being performed on m.

      • An interrupt action being performed on t.

      • If this is a timed wait, an internal action removing t from m's wait set that occurs after at least millisecs milliseconds plus nanosecs nanoseconds elapse since the beginning of this wait action.

      • An internal action by the implementation. Implementations are permitted, although not encouraged, to perform "spurious wake-ups", that is, to remove threads from wait sets and thus enable resumption without explicit instructions to do so.

    3. Thread t performs n lock actions on m.

    4. If thread t was removed from m's wait set in step 2 due to an interrupt, then t's interruption status is set to false and the wait method throws InterruptedException.

like image 29
xingbin Avatar answered Oct 13 '22 14:10

xingbin