内核中断处理流程
我只是在观看Heinz Kabutz的VJUG采访 ,这启发了我写一篇有关中断的文章。 顺便说一句,我建议您订阅VJUG YouTube频道 -确实非常有用。
Heinz始终是物有所值的,很难不学习很多东西就很难观看他的演讲。 他提出了如何处理InterruptedException
的主题,并假设很少有Java程序员可以正确地处理它。 我所读的关于Java的最喜欢的书– Java Concurrency In Practice (p138-144)中包含了我所阅读的关于线程中断的最佳解释。 如果您已阅读这些页面,您将知道如何正确处理InterruptedException
:-)
这是一个简短的摘要:
您多久遇到一次此代码:
.......
try {Thread.sleep(1000);
} catch(InterruptedException e){e.printStackTrace();
}
......
一个进程需要Hibernate一秒钟,但“烦人”必须处理InterruptedException
。 开发人员实际上并不知道如何处理此异常,因此只需将其记录到控制台即可。
这是非常不好的做法! 如果您确定线程永远不会中断(您是在封闭系统中编写此代码),则可能应该执行类似的操作,例如在catch块中抛出AssertionError
并添加注释,以免发生这种情况。 如果完全有可能线程被中断,那么您需要正确处理该中断。
可以通过调用其interrupt()
方法来中断线程。 这会将其中断状态设置为true,因此当您调用isInterrupted()
将返回true。 当调用interrupt()
,某些阻塞方法,例如Thread.sleep()
将抛出InterruptedException
。 请注意,触发InterruptedException
会将中断状态设置为false。 线程上有一个名为interrupted()
的方法,该方法像isInterrupted()
返回线程的中断状态,但关键是将中断状态设置回false。 ( interrupted()
是一个非常奇怪的命名方法,…)
在以下示例中,我们可以看到所有这些工作:
package util;/*** Created by daniel on 16/04/15.*/
public class Interrupt {public static void main(String[] args) {Thread sleeperThread = new Thread(){public void run(){try {Thread.sleep(1000);} catch (InterruptedException e) {System.out.println(isInterrupted()); //prints falseinterrupt();System.out.println(isInterrupted()); //prints trueSystem.out.println(interrupted()); //prints trueSystem.out.println(isInterrupted()); //prints false}}};sleeperThread.start();sleeperThread.interrupt();}
}
在实践中引用Java并发性:
“ API或语言规范中没有任何内容可以将中断与任何特定的取消语义联系起来,但实际上,对除中断之外的任何事物使用中断都是脆弱的,并且在大型应用程序中难以维持。”
换句话说,中断只是一个信号。 从理论上讲,您可以使用中断机制来指示线程执行所需的任何操作,也许可以执行操作A而不是执行操作B –但是我们建议您不要这样做。
.......
try {Thread.sleep(1000);
} catch(InterruptedException e){actionA();return;
}
actionB();
......
那么处理中断的正确方法是什么。 好吧,这取决于您的代码。 假设我们使用“正确”的中断作为取消,并且您的代码希望发生取消(应在文档中指定),那么您的代码应以受控方式取消其操作。 仅仅因为抛出异常并不意味着您必须匆忙退出而将一团糟留在身后。 因为您已经处理了中断,所以无需恢复线程上的中断状态。
如果您不希望中断,那么您应该适当地处理该中断(也许完成您正在做的事情),然后在线程上恢复该中断,以便在堆栈上端处理一些代码。 请记住,一旦引发异常,中断状态将设置为false。 这是应该如何完成的方式(摘自本书的代码):
public Task getNextTask(BlockingQueue<Task> queue){boolean interrupted = false;try{while(true){try{return queue.take();}catch(InterruptedException e){interrupted = true;//retry}}}finally {if(interrupted){Thread.currentThread().interrupt();}}}
翻译自: https://www.javacodegeeks.com/2015/04/dealing-with-interruptions.html
内核中断处理流程