Reputation: 34560
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?
Upvotes: 9
Views: 929
Reputation: 28289
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:
Thread t is added to the wait set of object m, and performs n unlock actions on m.
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.
Thread t performs n lock actions on m.
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.
Upvotes: 5
Reputation: 96444
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.
Upvotes: 6