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

2

9

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?

Buenrostro answered 2/5, 2018 at 13:12 Comment(1)
A well designed program should not have to wait for any significant amount of time to re-acquire the mutex. If your program keeps a mutex locked for any longer than a microsecond or so, then you're probably using it in a way that was not intended. Mutexes should only be used to prevent threads from interfering with each other when they access shared data. There are other tools (e.g., java.util.concurrent.*) that are better suited for making threads communicate and coordinate with each other.Umbles
A
6

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.

Allison answered 2/5, 2018 at 13:18 Comment(3)
It's also almost always the right pattern to re-interrupt the thread after catching the InterruptedException.Overstrung
@Gray: yes. but it would be better off not catching it at all here.Allison
Maybe dude. I rarely rethrow it but you are right that this might be a good place. I just always make sure peple know about reinterrupting since it's such an important pattern.Overstrung
D
5

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.

Dollhouse answered 2/5, 2018 at 13:23 Comment(3)
Thanks. Sorry that I marked the other answer as the solution, he was faster.Buenrostro
You can change your answer anytime @Buenrostro by just checking another answer. Your choice of answer should be able "rightness" more than speed.Overstrung
@fhucho: the JLS quote here is definitive and this is a very good answer (+1 from me). you can change your choice of answer whenever you want.Allison

© 2022 - 2024 — McMap. All rights reserved.