Java多线程之中断机制(如何处理中断?)(2)

因此,上面就是一个采用抛出异常的方式来结束线程的示例。尽管该示例的实用性不大。原因在 IBM的这篇博文中:我们 生吞了中断。

在第14行,我们直接catch了异常,然后打印输出了一下而已,调用栈中的更高层的代码是无法获得关于该异常的信息的。

第16行的e.printStackTrace()作用就相当于

“(仅仅记录 InterruptedException 也不是明智的做法,因为等到人来读取日志的时候,再来对它作出处理就为时已晚了。)”---摘自参考博文

上面我们是在run()方法中抛出异常,符合这里描述的:

有时候抛出 InterruptedException 并不合适,例如当由 Runnable 定义的任务调用一个 可中断的方法时,就是如此。在这种情况下,不能重新抛出 InterruptedException,但是 您也不想什么都不做。当一个阻塞方法检测到中断并抛出 InterruptedException 时,它 清除中断状态。如果捕捉到 InterruptedException 但是不能重新抛出它,那么应该保留 中断发生的证据,以便调用栈中更高层的代码能知道中断,并对中断作出响应。该任务可以 通过调用 interrupt() 以 “重新中断” 当前线程来完成,如清单 3 所示。 -----“摘自参考博文”

因为,run方法是实现的Runnable接口中的方法。不能像下面这样定义,也即上面所说的:“不能重新抛出InterruptedException”。

@Override public void run() throws InterruptedException{//这是错误的 //do something...

因此,一个更好的解决方案是:调用 interrupt() 以 “重新中断” 当前线程。改进MyThread类中catch异常的方式,如下:

1 public class MyThread extends Thread { 2 @Override 3 public void run() { 4 super.run(); 5 try{ 6 for (int i = 0; i < 500000; i++) { 7 if (this.interrupted()) { 8 System.out.println("should be stopped and exit"); 9 throw new InterruptedException(); 10 } 11 System.out.println("i=" + (i + 1)); 12 } 13 System.out.println("this line cannot be executed. cause thread throws exception"); 14 }catch(InterruptedException e){ 15 /**这样处理不好 16 * System.out.println("catch interrupted exception"); 17 * e.printStackTrace(); 18 */ 19 Thread.currentThread().interrupt();//这样处理比较好 20 } 21 } 22 }

这样,就由 生吞异常 变成了 将 异常事件 进一步扩散了。

参考博文:Java 理论与实践: 处理 InterruptedException 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/9953d3f03e8d2c02fd401ad2e43d0b54.html