用interrupt()中断Java线程- - JavaEye技术网站
最近在学习Java线程相关的东西,和大家分享一下,有错误之处欢迎大家指正.

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

Java代码

class ATask implements Runnable{    
   
    private double d = 0.0;    
        
    public void run() {    
       //死循环执行打印"I am running!" 和做消耗时间的浮点计算    
        while (true) {    
            System.out.println("I am running!");    
                
            for (int i = 0; i < 900000; i++) {    
                d =  d + (Math.PI + Math.E) / d;    
            }    
            //给线程调度器可以切换到其它进程的信号    
            Thread.yield();    
        }    
    }    
}    
   
public class InterruptTaskTest {    
        
    public static void main(String[] args) throws Exception{    
        //将任务交给一个线程执行    
        Thread t = new Thread(new ATask());    
        t.start();    
            
        //运行一断时间中断线程    
        Thread.sleep(100);    
        System.out.println("****************************");    
        System.out.println("Interrupted Thread!");    
        System.out.println("****************************");    
        t.interrupt();    
    }    
}    
class ATask implements Runnable{

 

  private double d = 0.0;

  

  public void run() {

   //死循环执行打印"I am running!" 和做消耗时间的浮点计算

   while (true) {

     System.out.println("I am running!");

     

     for (int i = 0; i < 900000; i++) {

      d =  d + (Math.PI + Math.E) / d;

     }

     //给线程调度器可以切换到其它进程的信号

     Thread.yield();

   }

  }

}

 

public class InterruptTaskTest {

  

  public static void main(String[] args) throws Exception{

   //将任务交给一个线程执行

   Thread t = new Thread(new ATask());

   t.start();

   

   //运行一断时间中断线程

   Thread.sleep(100);

   System.out.println("****************************");

   System.out.println("Interrupted Thread!");

   System.out.println("****************************");

   t.interrupt();

  }

} 



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

Java代码

......    
I am running!    
I am running!    
I am running!    
I am running!    
****************************    
Interrupted Thread!    
****************************    
I am running!    
I am running!    
I am running!    
I am running!    
I am running!    
....   
......

I am running!

I am running!

I am running!

I am running!

****************************

Interrupted Thread!

****************************

I am running!

I am running!

I am running!

I am running!

I am running!

....

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

Java代码

class ATask implements Runnable{    
   
    private double d = 0.0;    
        
    public void run() {    
       //死循环执行打印"I am running!" 和做消耗时间的浮点计算    
        try {    
            while (true) {    
                System.out.println("I am running!");    
                    
                for (int i = 0; i < 900000; i++) {    
                    d =  d + (Math.PI + Math.E) / d;    
                }    
                //休眠一断时间,中断时会抛出InterruptedException    
                Thread.sleep(50);    
            }    
        } catch (InterruptedException e) {    
            System.out.println("ATask.run() interrupted!");    
        }    
    }    
}   
class ATask implements Runnable{

 

  private double d = 0.0;

  

  public void run() {

   //死循环执行打印"I am running!" 和做消耗时间的浮点计算

   try {

     while (true) {

      System.out.println("I am running!");

      

      for (int i = 0; i < 900000; i++) {

        d =  d + (Math.PI + Math.E) / d;

      }

      //休眠一断时间,中断时会抛出InterruptedException

      Thread.sleep(50);

     }

   } catch (InterruptedException e) {

     System.out.println("ATask.run() interrupted!");

   }

  }

}


程序运行结果如下:

Java代码

I am running!   
I am running!   
****************************   
Interrupted Thread!   
****************************   
ATask.run() interrupted!  
I am running!

I am running!

****************************

Interrupted Thread!

****************************

ATask.run() interrupted!


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

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

Java代码

class ATask implements Runnable{    
   
    private double d = 0.0;    
        
    public void run() {    
            
        //检查程序是否发生中断    
        while (!Thread.interrupted()) {    
            System.out.println("I am running!");    
   
            for (int i = 0; i < 900000; i++) {    
                d = d + (Math.PI + Math.E) / d;    
            }    
        }    
   
        System.out.println("ATask.run() interrupted!");    
    }    
}   
class ATask implements Runnable{

 

  private double d = 0.0;

  

  public void run() {

   

   //检查程序是否发生中断

   while (!Thread.interrupted()) {

     System.out.println("I am running!");

 

     for (int i = 0; i < 900000; i++) {

      d = d + (Math.PI + Math.E) / d;

     }

   }

 

   System.out.println("ATask.run() interrupted!");

  }

}

程序运行结果如下:

Java代码

I am running!   
I am running!   
I am running!   
I am running!   
I am running!   
I am running!   
I am running!   
****************************   
Interrupted Thread!   
****************************   
ATask.run() interrupted!  
I am running!

I am running!

I am running!

I am running!

I am running!

I am running!

I am running!

****************************

Interrupted Thread!

****************************

ATask.run() interrupted!



我们可结合使用两种方法来达到可以通过interrupt()中断线程.请看下面例子:

Java代码

class ATask implements Runnable{    
   
    private double d = 0.0;    
        
    public void run() {    
            
        try {    
        //检查程序是否发生中断    
        while (!Thread.interrupted()) {    
            System.out.println("I am running!");    
            //point1 before sleep    
            Thread.sleep(20);    
            //point2 after sleep    
            System.out.println("Calculating");    
            for (int i = 0; i < 900000; i++) {    
                d = d + (Math.PI + Math.E) / d;    
            }    
        }    
            
        } catch (InterruptedException e) {    
            System.out.println("Exiting by Exception");    
        }    
            
        System.out.println("ATask.run() interrupted!");    
    }    
}   
class ATask implements Runnable{

 

  private double d = 0.0;

  

  public void run() {

   

   try {

   //检查程序是否发生中断

   while (!Thread.interrupted()) {

     System.out.println("I am running!");

     //point1 before sleep

     Thread.sleep(20);

     //point2 after sleep

     System.out.println("Calculating");

     for (int i = 0; i < 900000; i++) {

      d = d + (Math.PI + Math.E) / d;

     }

   }

   

   } catch (InterruptedException e) {

     System.out.println("Exiting by Exception");

   }

   

   System.out.println("ATask.run() interrupted!");

  }

}


在point1之前处point2之后发生中断会产生两种不同的结果,可以通过修改InterruptTaskTest main()里的Thread.sleep()的时间来达到在point1之前产生中断或在point2之后产生中断.
如果在point1之前发生中断,程序会在调用Thread.sleep()时抛出InterruptedException从而结束线程.这和在Thread.sleep()时被中断是一样的效果.程序运行结果可能如下:

Java代码

I am running!   
Calculating   
I am running!   
Calculating   
I am running!   
Calculating   
I am running!   
****************************   
Interrupted Thread!   
****************************   
Exiting by Exception   
ATask.run() interrupted!  
I am running!

Calculating

I am running!

Calculating

I am running!

Calculating

I am running!

****************************

Interrupted Thread!

****************************

Exiting by Exception

ATask.run() interrupted!


如果在point2之后发生中断,线程会继续执行到下一次while判断中断状态时.程序运行结果可能如下:

Java代码

I am running!   
Calculating   
I am running!   
Calculating   
I am running!   
Calculating   
****************************   
Interrupted Thread!   
****************************   
ATask.run() interrupted!  


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/kjniuzemin2003/archive/2009/06/30/4309876.aspx
郑重声明:资讯 【用interrupt()中断Java线程- - JavaEye技术网站】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——