如果 wait() 抛出 InterruptedException,线程是否等待直到它获取对象的监视器?
If wait() throws an InterruptedException, does the thread wait until it acquires the object's monitor?
例如:
public synchronized Object get() {
while (result == null) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
// Do we own the monitor of this object?
}
}
return result;
}
当e.printStackTrace()
执行时,我们是否保证拥有对象的监视器?
引用说当 wait()
returns 在 notify()
或 notifyAll()
调用之后,线程等待直到它获取对象的监视器。但是如果 wait()
抛出异常呢?
到等待returns时(包括它抛出InterruptedException的情况)线程必须有监视器,否则它不能执行同步方法。线程在离开 wait 方法之前必须获取监视器。然后,一旦它退出等待方法,线程就会拥有监视器,并在线程离开该方法时释放它。
这里最好将InterruptedException 抛给调用者而不是吃掉它。您的目标是快速离开并让呼叫者知道发生了中断,以便它可以结束。在这里吃它似乎也意味着你再次回到 while 循环。 java.util.concurrent 使用中断来实现取消,特别是如果您使用 java.util.concurrent 工具,编写与它们兼容的代码是有意义的。
是的。其实这个InterruptedException
是重新获取监听后抛出的
参见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.
例如:
public synchronized Object get() {
while (result == null) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
// Do we own the monitor of this object?
}
}
return result;
}
当e.printStackTrace()
执行时,我们是否保证拥有对象的监视器?
引用说当 wait()
returns 在 notify()
或 notifyAll()
调用之后,线程等待直到它获取对象的监视器。但是如果 wait()
抛出异常呢?
到等待returns时(包括它抛出InterruptedException的情况)线程必须有监视器,否则它不能执行同步方法。线程在离开 wait 方法之前必须获取监视器。然后,一旦它退出等待方法,线程就会拥有监视器,并在线程离开该方法时释放它。
这里最好将InterruptedException 抛给调用者而不是吃掉它。您的目标是快速离开并让呼叫者知道发生了中断,以便它可以结束。在这里吃它似乎也意味着你再次回到 while 循环。 java.util.concurrent 使用中断来实现取消,特别是如果您使用 java.util.concurrent 工具,编写与它们兼容的代码是有意义的。
是的。其实这个InterruptedException
是重新获取监听后抛出的
参见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.