如果您InterruptedException
在 for 循环内的任何地方捕获,请删除所有这些 try/catch 块,而是使用一个包围整个 for 循环的 try/catch。当您中断其线程时,这将允许整个 for 循环停止。
同样,如果您正在捕捉IOException
,请先捕捉InterruptedIOException
和ClosedByInterruptException
。将这些 catch 块移到 for 循环之外。(如果您在内部捕获,编译器将不允许它IOException
,因为在外部级别没有什么可以捕获的。)
如果阻塞调用没有抛出InterruptedException
,则需要在每个调用之后添加一个检查,如下所示:
if (Thread.interrupted()) {
break;
}
如果您有许多级别的循环,您可能需要添加一个标签,以便您可以直接退出第一个“指令”循环,而无需添加大量标志变量:
instructions:
for ( ... ) {
for ( ... ) {
doLongOperation();
if (Thread.interrupted()) {
break instructions;
}
}
}
无论哪种方式,一旦处理了中断,您就可以让后台线程中断您的第一个 for 循环:
final Thread instructionsThread = Thread.currentThread();
Runnable interruptor = new Runnable() {
public void run() {
instructionsThread.interrupt();
}
};
ScheduledExecutorService executor =
Executors.newSingleThreadScheduledExecutor();
executor.schedule(interruptor, 5, TimeUnit.MINUTES);
// instructions
try {
for ( ... ) {
}
} catch (InterruptedException |
InterruptedIOException |
ClosedByInterruptException e) {
logger.log(Level.FINE, "First loop timed out.", e);
} finally {
executor.shutdown();
}
// instructions2