zoukankan      html  css  js  c++  java
  • Thread interrupt() 方法的使用

    原文地址:http://blog.csdn.net/biangren/article/details/7522583

    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!  
  • 相关阅读:
    【Docker 命令】- ps命令
    【Docker 命令】- exec命令
    【Docker 命令】- create命令
    【Docker 命令】- pause/unpause 命令
    【Docker 命令】- rm命令
    【Docker 命令】- kill命令
    【Docker 命令】- start/stop/restart命令
    【Docker 命令】- run命令
    【Docker】- 基本命令
    深度学习原理与框架- batch_normalize(归一化操作)
  • 原文地址:https://www.cnblogs.com/scud001/p/3812996.html
Copyright © 2011-2022 走看看