从互联网上的多篇文章来看,建议不要吞咽InterruptedException
。当我要重用同一个线程时,使用类似这样的线程池执行器来执行此操作更有意义。
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> future = executor.submit(() -> {
printNumbers(); // first call
printNumbers(); // second call
});
Thread.sleep(3_000);
executor.shutdownNow(); // will interrupt the task
executor.awaitTermination(3, TimeUnit.SECONDS);
}
private static void printNumbers() {
for (int i = 0; i < 10; i++) {
System.out.print(i);
try {
Thread.sleep(1_000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // preserve interruption status
break;
}
}
}
上面的代码示例来自DZone https://dzone.com/articles/understanding-thread-interruption-in-java.
但在每次创建新线程的情况下,例如:
Object LOCK = new Object();
public void doSomeJob() {
myThread = new Thread(new Runnable() {
public void run() {
try {
synchronized(LOCK) {
System.out.println("Inside run");
LOCK.wait();
}
} catch(InterruptedException ignored){}
}
}
}
我还需要打电话吗Thread.currentThread().interrupt();
?这有意义吗?
好的参考资料:
https://codepumpkin.com/interrupt-interrupted-isinterrupted-java-multithreading/ https://codepumpkin.com/interrupt-interrupted-isinterrupted-java-multithreading/
http://michaelscharf.blogspot.com/2006/09/dont-swallow-interruptedexception-call.html http://michaelscharf.blogspot.com/2006/09/dont-swallow-interruptedexception-call.html
我将根据部分给出答案7.1.2伟大的书并发实践 https://rads.stackoverflow.com/amzn/click/com/0321349601作者:布莱恩·戈茨。
在你的第一个例子中你使用ExecutorService
. ExecutorService
管理它自己的线程。你不是那些的所有者Threads所以你不知道打扰对他们意味着什么(例如线程池可能会选择杀人Threads被打断并创建新的)。这就是为什么当您向该池提交可取消的任务时应该保留中断状态。此引文适用于本案:
任务不在它们拥有的线程中执行。它们借用线程池等服务拥有的线程。编码
不拥有线程(对于线程池,线程池实现之外的任何代码)应该小心
保留中断状态,以便所属代码最终可以对其进行操作,即使“来宾”代码对
中断也是如此。 (如果你为某人看家,你不会扔掉他们不在时收到的邮件 - 你会保存它并让他们回来时处理它,即使你确实阅读了他们的杂志。)
在第二种情况下,您管理一个实例Thread手动。所以你是它的所有者。然后你决定中断对此意味着什么Thread并且您不必保留中断状态在第二种情况下,如果您不想应用任何线程中断策略为了它 :
你不应该做的就是吞下InterruptedException
通过捕获它并且在 catch 块中不执行任何操作,除非您的代码实际上正在实现线程的中断策略
另请注意线程中断策略不同于任务取消政策 :
-
线程中断策略- 定义线程如何响应中断(例如
ThreadPool
可能会杀死被中断的线程并创建一个新线程)。它由线程的所有者定义。
-
任务取消政策- 定义任务如何对取消做出反应。取消通常是通过中断来实现的。执行任务的人选择任务是否响应中断。如果您的任务调用抛出异常的方法,那么这很容易实现
InterruptedException
。或者您可以通过调用检查线程的中断标志Thread::isInterrupted
(例如在循环中)。任务的实施者选择如何处理这个问题。
另外,您不应该对线程中断策略做出任何假设(如果您不是线程中断策略的所有者)Thread
)。这就是为什么保留中断状态或重新抛出InterruptedException
被认为是一个好的做法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)