首页 > 代码库 > Thread interrupt() 方法的使用

Thread interrupt() 方法的使用

 

interrupt()只是改变中断状态而已:
       interrupt()不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态.如果线程没有被阻塞,这时调用interrupt()将不起作用;仅仅是设置中断标志位为true

 

同时注意下面三个方法的区别:

publicvoid interrupt()

public static boolean interrupted():线程的中断状态由该方法清除

public boolean isInterrupted() :测试线程是否已经中断。线程的中断状态不受该方法的影响。 

总结:

     

       t.interrupt()不会中断正在执行的线程,只是将线程的标志位设置成true。但是如果线程在调用sleep(),join(),wait()方法时线程被中断,则这些方法会抛出InterruptedException,在catch块中捕获到这个异常时,线程的中断标志位已经被设置成false了,因此在此catch块中调用t.isInterrupted(),Thread.interrupted()始终都为false, 

而t.isInterrupted与Thread.interrupted()的区别是API中已经说明很明显了,Thread.interrupted()假如当前的中断标志为true,则调完后会将中断标志位设置成false ,而t.isInterrupted对标志位不做任何处理

 

 

假如我们有一个任务如下,交给一个Java线程来执行,如何才能保证调用interrupt()来中断它呢? 

Java代码
  1. class ATask implements Runnable{   
  2.   
  3.     private double d = 0.0;   
  4.        
  5.     public void run() {   
  6.         //死循环执行打印"I am running!" 和做消耗时间的浮点计算   
  7.         while (true) {   
  8.              System.out.println("I am running!");   
  9.                
  10.             for (int i = 0; i < 900000; i++) {   
  11.                  d =   d + (Math.PI + Math.E) / d;   
  12.              }   
  13.             //给线程调度器可以切换到其它进程的信号   
  14.              Thread.yield();   
  15.          }   
  16.      }   
  17. }   
  18.   
  19. public class InterruptTaskTest {   
  20.        
  21.     public static void main(String[] args) throws Exception{   
  22.         //将任务交给一个线程执行   
  23.          Thread t = new Thread(new ATask());   
  24.          t.start();   
  25.            
  26.         //运行一断时间中断线程   
  27.          Thread.sleep(100);   
  28.          System.out.println("****************************");   
  29.          System.out.println("Interrupted Thread!");   
  30.          System.out.println("****************************");   
  31.          t.interrupt();   
  32.      }   
  33. }   



运行这个程序,我们发现调用interrupt()后,程序仍在运行,如果不强制结束,程序将一直运行下去,如下所示: 

Java代码
  1. ......   
  2. I am running!   
  3. I am running!   
  4. I am running!   
  5. I am running!   
  6. ****************************   
  7. Interrupted Thread!   
  8. ****************************   
  9. I am running!   
  10. I am running!   
  11. I am running!   
  12. I am running!   
  13. I am running!   
  14. ....  


虽然中断发生了,但线程仍然在进行,离开线程有两种常用的方法: 
抛出InterruptedException和用Thread.interrupted()检查是否发生中断,下面分别看一下这两种方法: 
1.在阻塞操作时如Thread.sleep()时被中断会抛出InterruptedException(注意,进行不能中断的IO操作而阻塞和要获得对象的锁调用对象的synchronized方法而阻塞时不会抛出InterruptedException) 

Java代码
  1. class ATask implements Runnable{   
  2.   
  3.     private double d = 0.0;   
  4.        
  5.     public void run() {   
  6.         //死循环执行打印"I am running!" 和做消耗时间的浮点计算   
  7.         try {   
  8.             while (true) {   
  9.                  System.out.println("I am running!");   
  10.                    
  11.                 for (int i = 0; i < 900000; i++) {   
  12.                      d =   d + (Math.PI + Math.E) / d;   
  13.                  }   
  14.                 //休眠一断时间,中断时会抛出InterruptedException   
  15.                  Thread.sleep(50);   
  16.              }   
  17.          } catch (InterruptedException e) {   
  18.              System.out.println("ATask.run() interrupted!");   
  19.          }   
  20.      }   
  21. }  


程序运行结果如下: 

Java代码
  1. I am running!   
  2. I am running!   
  3. ****************************   
  4. Interrupted Thread!   
  5. ****************************   
  6. ATask.run() interrupted!  


可以看到中断任务时让任务抛出InterruptedException来离开任务. 

2.Thread.interrupted()检查是否发生中断.Thread.interrupted()能告诉你线程是否发生中断,并将清除中断状态标记,所以程序不会两次通知你线程发生了中断. 

Java代码
  1. class ATask implements Runnable{   
  2.   
  3.     private double d = 0.0;   
  4.        
  5.     public void run() {   
  6.            
  7.         //检查程序是否发生中断   
  8.         while (!Thread.interrupted()) {   
  9.              System.out.println("I am running!");   
  10.   
  11.             for (int i = 0; i < 900000; i++) {   
  12.                  d = d + (Math.PI + Math.E) / d;   
  13.              }   
  14.          }   
  15.   
  16.          System.out.println("ATask.run() interrupted!");   
  17.      }   
  18. }  


程序运行结果如下: 

Java代码
    1. I am running!   
    2. I am running!   
    3. I am running!   
    4. I am running!   
    5. I am running!   
    6. I am running!   
    7. I am running!   
    8. ****************************   
    9. Interrupted Thread!   
    10. ****************************   
    11. ATask.run() interrupted!