在java早期的版本中,提供了一个终止线程的方法:stop()。但在随后的版本中,这个方法被遗弃了,因为它的中断是”立即“,这样有可能会造成数据不一致的情况。比如说在转账的过程中。因此在jdk1.5的时候,有一个方法出来解决这个问题:intertupt()。这个方法会在run()中止,【Interrupting a thread that is not alive need not have any effect.】,这样就不会造成数据不一致的问题。但是很多人在使用这个方法的时候还是出现了问题。以下举出一个例子:
public class ThreadTest extends Thread {
int count=0;
public void run(){
System.out.println(getName()+"将要运行...");
while(!this.isInterrupted()){
System.out.println(getName()+"运行中"+count++);
try{
Thread.sleep(400);
}catch(InterruptedException e){
System.out.println(getName()+"从阻塞中退出...");
System.out.println("this.isInterrupted()="+this.isInterrupted());
}
}
System.out.println(getName()+"已经终止!");
}
}
public class ThreadDemo {
public static void main(String argv[])throws InterruptedException{
ThreadTest ta=new ThreadTest();
ta.setName("ThreadTest");
ta.start();
Thread.sleep(2000);
System.out.println(ta.getName()+"将要被中断");
ta.interrupt();
System.out.println("ta.isInterrupted()="+ta.isInterrupted());
}
}
以下给出运行结果:
可见【中断】之后,程序还在继续运行着。为什么呢?sleep的时候,调用了interupt会抛出异常,让线程重新处于非中断状态。修复这个bug的方法是可以用一个标志位来解决。
public class ThreadTest extends Thread {
private boolean isInterrupted=false;
int count=0;
public void interrupt(){
isInterrupted = true;
super.interrupt();
}
public void run(){
System.out.println(getName()+"将要运行...");
while(!isInterrupted){
System.out.println(getName()+"运行中"+count++);
try{
Thread.sleep(400);
}catch(InterruptedException e){
System.out.println(getName()+"从阻塞中退出...");
System.out.println("this.isInterrupted()="+this.isInterrupted());
}
}
System.out.println(getName()+"已经终止!");
}
}
这样就可以解决以上存在问题。
注意:
当线程再读取大文件数据时,调用interrupt也是无效的。这个时候,我们也可以通过标志位,来解决。比如说中断的状态检测到了,我们就强制关闭流通过调用close方法。