这篇文章主要记录使用 interrupt() 方法中断线程,以及如何对InterruptedException进行处理。感觉对InterruptedException异常进行处理是一件谨慎且有技巧的活儿。
由于使用stop()方法停止线程非常的暴力,人家线程运行的好好的,突然就把人家杀死了,线程占用的锁被强制释放,极易导致数据的不一致性。可参考这篇文章对stop()方法的介绍。
因此,提出了一种温和的方式:请求另外一个线程不要再执行了,这就是中断方式。
二,中断及如何响应中断?
如何优雅地响应中断真的是太高深了,看到这篇文章:Java 理论与实践: 处理 InterruptedException就吓了一跳。下面只是记录一些最简单的我对响应中断的理解。
假设某个线程要不停地处理某件事情(比如 i 一直自增),但是还有个要求:在处理事情前,先要检查下这个线程是否被中断,如果已经被中断,处理就应该结束。
下面是一些例子,这些例子摘自《Java多线程核心编程技术》
1 public class Run { 2 3 public static void main(String[] args) { 4 try { 5 MyThread thread = new MyThread(); 6 thread.start(); 7 Thread.sleep(2000); 8 thread.interrupt();//请求中断MyThread线程 9 } catch (InterruptedException e) { 10 System.out.println("main catch"); 11 e.printStackTrace(); 12 } 13 System.out.println("end!"); 14 } 15 }
main线程睡眠2000ms后,执行第8行中断MyThread线程。
1 public class MyThread extends Thread { 2 @Override 3 public void run() { 4 super.run(); 5 for (int i = 0; i < 500000; i++) { 6 if (this.interrupted()) { 7 System.out.println("should be stopped and exit"); 8 break; 9 } 10 System.out.println("i=" + (i + 1)); 11 } 12 System.out.println("this line is also executed. thread does not stopped");//尽管线程被中断,但并没有结束运行。这行代码还是会被执行 13 } 14 }
当MyThread获得CPU执行时,第6行的 if 测试中,检测到中断标识被设置。即MyThread线程检测到了main线程想要中断它的 请求。
大多数情况下,MyThread检测到了中断请求,对该中断的响应是:退出执行(或者说是结束执行)。
但是,上面第5至8行for循环,是执行break语句跳出for循环。但是,线程并没有结束,它只是跳出了for循环而已,它还会继续执行第12行的代码....
因此,我们的问题是,当收到了中断请求后,如何结束该线程呢?
一种可行的方法是使用 return 语句 而不是 break语句。。。。。哈哈。。。
当然,一种更优雅的方式则是:抛出InterruptedException异常。
看下面MyThread类的代码:
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 System.out.println("catch interrupted exception"); 16 e.printStackTrace(); 17 } 18 } 19 }
当MyThread线程检测到中断标识为true后,在第9行抛出InterruptedException异常。这样,该线程就不能再执行其他的正常语句了(如,第13行语句不会执行)。