关于线程中断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并发编程:设计原则与模式

你可能感兴趣的:(设计模式,thread,多线程,编程)