关于线程中止thread interrupt
关于线程中断thread interrupt
在多线程编程中经常会遇到需要中止线程的情况,比如启动多个线程去数据库中搜索,如果有一个线程返回了结果,其他线程就可以取消了(Thread.stop()已经建议不要再使用)
1.通过成员方法Thread.interrupt()来设置中断状态为true
2.通过成员方法Thread.isInterrupted()来获取中断状态
3.通过静态方法Thread.interrupted()来获取中断状态,并且清除中断状态(当然获取的是清除之前的值),也就是说连续两次调用此方法,第二次一定会返回false,当然也有例外,具体看文档。
通常可以通过如下示例代码来控制线程退出,
public void run() { while(flag) { //执行的代码 } }
flag为false时线程停止。。。
下面测试线程被中断后的情况
public class ThreadInterruptTest { public static void main(String[] args) { Thread subThread = new Thread(new Runnable() { @Override public void run() { boolean flag = false; while (!flag) { System.out.println(".....子线程运行中......"); try { Thread.sleep(1000); } catch (InterruptedException e) { // Thread.currentThread().interrupt(); flag = Thread.interrupted(); } } System.out.println("子线程退出"); } }); subThread.start(); //主线程休息3s try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } subThread.interrupt(); //中断子线程 } }
运行上面的程序,会发现即便主线程调用了interrupt方法,子线程检测到异常后发现中断状态没有被置为true,导致循环不能退出,子线程不能退出,但是静态方法Thread.interrupted()的注释说: @return true if the current thread has been interrupted;false otherwise.
后来在Doug lea的书中找到了答案,根据规范,这是因为在sleep方法睡眠后,如果检测到InterruptedException异常被抛出,中断状态会被重新置为false,具体可能要看openjdk的c源码,后来我在The Java Language Specification也找到了相关的描述,If thread t is interrupted, an InterruptedException is thrown and t's interruption status is set to false.
如果我们处理完InterruptedException异常后需要保持并传递该中断状态的话只要再次调用Thread.currentThread().interrupt(),将中断状态置为true就好了,也就是上面注释掉的那一句
ps:参考Java并发编程:设计原则与模式