我的问题与投掷Thread.sleep(...)
的所有方法(包括InterruptedException
)有关。
我发现有关Sun的教程的声明
InterruptedException
是一个异常,sleep
在另一个线程在睡眠处于活动状态时中断当前线程时抛出。
这是否意味着如果在中断时sleep
未激活,将忽略中断?
假设我有两个主题:threadOne
和threadTwo
。 threadOne
创建并启动threadTwo
。 threadTwo
执行runnable,其run方法类似于:
public void run() {
:
:
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
return;
}
:
:
: // In the middle of two sleep invocations
:
:
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
return;
}
:
:
}
创建线程后,threadOne
会中断threadTwo
。假设threadTwo
在中断时(当没有睡眠方法处于活动状态时)处于两次睡眠调用的中间,那么第二次睡眠方法会在调用后立即抛出InterrupteException
吗? p>
如果没有,那么这个中断会永远被忽略吗?
如何确保threadTwo
始终知道中断(无论其中一种睡眠方法是否有效)都无关紧要?
答案 0 :(得分:3)
来自javadoc:
如果此线程被阻止 调用wait(),wait(long), 或等待(long,int)方法 对象类,或者join(), join(long),join(long,int), 睡觉(长),或睡觉(长,int), 这个类的方法,然后它的 中断状态将被清除 它会收到一个 InterruptedException的。
如果此线程在I / O中被阻止 对可中断的操作 然后通道将是通道 关闭,线程的中断状态 将被设置,线程将 收到ClosedByInterruptException。
如果此线程被阻止 然后选择线程的中断 状态将被设置,它将返回 立即从选择 操作,可能是非零 值,就像选择器一样 唤醒唤醒方法。
如果没有以前的条件 然后保持这个线程的中断 状态将被设置。
这意味着您必须检查中断状态以确保您的线程知道中断。这可以通过两种方法完成:isInterrupted()和interrupted()。最后一个清除了中断状态。
这样的事情:
while(!Thread.interrupted()) {
...
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
return;
}
}
答案 1 :(得分:2)
在Sun的Windows JDK上,线程实际上会在输入InterruptedException
时抛出sleep()
:
public static final void main(String args[]) throws Exception {
final Thread main = Thread.currentThread();
Thread t = new Thread() {
@Override
public void run() {
main.interrupt();
}
};
t.start();
t.join();
Thread.sleep(1000);
System.out.println("Not interrupted!");
}
sleep()
的API文档可以解释为这是强制性行为:
抛出InterruptedException - 如果有的话 线程已中断当前 线。中断的状态 当前线程被清除 抛出异常。
但这不是很清楚,所以我不会依赖它,而是手动检查isInterrupted()
。
答案 2 :(得分:2)
Java文档有点误导。如果设置了线程的中断状态,则在该线程上调用sleep()
将导致立即抛出InterruptException
。
即使线程在调用 sleep()
之前被中断,这也适用。
如上所述,您也可以查看Thread.isInterrupted()
是否要自行处理中断。
答案 3 :(得分:-1)
InterruptionException仅在线程休眠期间感兴趣。如果线程在之前的任何地方被中断,则后面的sleep()调用不会抛出它。只有sleep()时的中断才有意义,因为它会完全打破sleep()调用。