Java更多的库谜题84:被粗暴地中断

Java更多的库谜题84:被粗暴地中断,第1张

Java更多的库谜题84:被粗暴地中断,第2张

在下面的程序中,一个线程试图中断自己,然后检查中断是否成功。它会打印什么?
公共类SelfInterruption {
公共静态void main(String[]args){
thread . current thread()。中断();
if(thread . Interrupted()){
system . out . println(" Interrupted:"+
thread . Interrupted());
} else {
system . out . println("未中断:"+
thread . interrupted());
}
}
}

虽然线程中断自己的情况并不常见,但也不是闻所未闻。当一个方法捕捉到一个InterruptedException并且没有准备好处理它时,它通常会重新抛出这个异常。但是,因为这是一个“检查异常”,所以只有在方法声明允许的情况下,方法才能重新引发异常。如果无法重新抛出,该方法可以通过中断当前线程来“重建”异常。这个方法效果很好,所以这个程序中的线程自己中断应该没有问题。因此,程序应该进入if语句的第一个分支,并打印出Interrupted: true。如果你运行程序,你会发现事实并非如此。但是它不打印未中断:假,它打印中断:假。
看来程序无法确定线程是否中断。当然,这种观点毫无意义。实际情况是,Thread.interrupted方法第一次调用时返回true,线程的中断状态被清除,所以在if-then-else语句的分支中第二次调用时返回false。调用Thread.interrupted方法总是会清除当前线程的中断状态。方法的名字并没有为这种行为提供任何线索,但是对于5.0版本,相应文档中有一句话也是误导:“测试当前线程是否中断”[Java-API]。所以很多程序员没有意识到Thread.interrupted方法会影响线程的中断状态也就可以理解了。
Thread类有两种方法来查询线程的中断状态。另一个方法是名为isInterrupted的实例方法,它不清除线程的中断状态。如果用这个方法重写程序,会打印出想要的结果true:
public class self interruption {
public static void main(string[]args){
thread . current thread()。中断();
if(Thread.currentThread()。is Interrupted()){
system . out . println(" Interrupted:"+
thread . current thread()。is interrupted());
} else {
system . out . println("未中断:"+
Thread.currentThread()。is interrupted());
}
}
}

这个谜题的教训是:不要使用Thread.interrupted方法,除非你想清除当前线程的中断状态。如果只是想查询中断状态,请使用isInterrupted方法。这里给API设计者的教训是,方法的名字应该用来描述它们的主要功能。根据Thread.interrupted方法的行为,它的名称应该是clearInterruptStatus,因为它的返回值相对于它对中断状态的更改来说是次要的。尤其是当一个方法的名字并不完美的时候,文档能否清晰的描述它的行为就显得非常重要。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » Java更多的库谜题84:被粗暴地中断

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情