【发布时间】:2018-07-27 12:38:28
【问题描述】:
我想中断一个线程,该线程在无限循环的每个增量中检查中断标志。退出循环的唯一方法是抛出 InterruptedException。
在可中断线程执行的(不可访问的)代码中的某处,睡眠操作正在声明一个 InterruptedException 和一个捕获异常的 catch 块。在不幸的情况下,线程将在 sleep 方法正在执行时被中断,导致中断标志被重置。在这种情况下,线程不会退出无限的 while 循环。
避免这种情况的最佳策略是什么?下面代码中的主线程在循环中调用中断,直到可中断线程不再活动。这是一个合理的策略吗?有哪些替代方案?
public class InterruptableThreads extends Thread {
public static Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException();
}
try {
Thread.sleep(5000);
} catch (Exception e) {
System.out.println("Swallowing exception. Resetting interrupted flag");
}
System.out.println("t1 run");
}
} catch (InterruptedException e) {
System.err.println("t1 interrupted.");
}
}
});
public static void main(String[] args) throws InterruptedException {
t1.start();
Thread.sleep(4000);
while (t1.isAlive()) {
t1.interrupt();
}
t1.join(1000);
System.out.println("Finished!");
}
}
【问题讨论】:
-
catch block where the exception is swallowed.这总是一个坏主意。正确的方法是抛出异常(不捕获它)或重置 catch 块中的中断标志。 -
我知道这是个坏主意。我无权访问这部分遗留代码。
-
你试过了吗?你确定不可访问的代码有调用可中断方法而不吞下InterruptedException的地方吗?否则你会永远等待,唯一的办法就是调用 Thread.stop()。
-
我试过了,代码肯定会吞下异常,它的一个不好的副作用是“中断”标志被重置,所以我的条件没有结束while循环围绕此代码。 (这是一个极不可能的星座和罕见的情况,每 5 年发生一次)我的 sn-p 建议一个解决方案,通过在有问题的线程上重复调用中断,希望在某个时刻它会到达它而不是在睡眠中部分。我的问题是这个解决方案是否合法。
标签: java multithreading concurrency