不提倡的stop()方法
臭名昭著的stop()停止线程的方法已不提倡使用了,原因是什么呢?
当在一个线程对象上调用stop()方法时,这个线程对象所运行的线程就会立即停止,并抛出特殊的ThreadDeath()异常。这里的“立即”因为太“立即”了,
假如一个线程正在执行:
synchronized void { x = 3; y = 4;} 由于方法是同步的,多个线程访问时总能保证x,y被同时赋值,而如果一个线程正在执行到x = 3;时,被调用了 stop()方法,即使在同步块中,它也干脆地stop了,这样就产生了不完整的残废数据。而多线程编程中最最基础的条件要保证数据的完整性,所以请忘记 线程的stop方法,以后我们再也不要说“停止线程”了。
如何才能“结束”一个线程?
interupt()中断线程
一个线程从运行到真正的结束,应该有三个阶段:
正常运行.
处理结束前的工作,也就是准备结束.
结束退出.
那么如何让一个线程结束呢?既然不能调用stop,可用的只的interrupt()方法。但interrupt()方法只是改变了线程的运行状态,如何让它退出运行?对于一般逻辑,只要线程状态已经中断,我们就可以让它退出,这里我们定义一个线程类ThreadA,所以这样的语句可以保证线程在中断后就能结束运行:
while(!isInterrupted()){ 正常逻辑 }
,一个测试类,ThreadDemo
这样ThreadDemo调用interrupt()方法,isInterrupted()为true,就会退出运行。但是如果线程正在执行wait,sleep,join方法,你调用interrupt()方法,这个逻辑就不完全了。
我们可以这样处理:
public void run(){ while(!isInterrupted()){ try{ 正常工作 }catch(InterruptedException e){ //nothing } } } }想一想,如果一个正在sleep的线程,在调用interrupt后,会如何?wait方法检查到isInterrupted()为true,抛出异常, 而你又没有处理。而一个抛出了InterruptedException的线程的状态马上就会被置为非中断状态,如果catch语句没有处理异常,则下一 次循环中isInterrupted()为false,线程会继续执行,可能你N次抛出异常,也无法让线程停止。
这个错误情况的实例代码
ThreadA
public class ThreadA 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()+"已经终止!");
}
}
ThreadDemo
public class ThreadDemo ...{
public static void main(String argv[])throws InterruptedException...{
ThreadA ta=new ThreadA();
ta.setName("ThreadA");
ta.start();
Thread.sleep(2000);
System.out.println(ta.getName()+"正在被中断...");
ta.interrupt();
System.out.println("ta.isInterrupted()="+ta.isInterrupted());
}
}
那么如何能确保线程真正停止?在线程同步的时候我们有一个叫“二次惰性检测”(double check),能在提高效率的基础上又确保线程真正中同步控制中。那么我把线程正确退出的方法称为“双重安全退出”,即不以isInterrupted ()为循环条件。而以一个标记作为循环条件:
正确的ThreadA代码是:
public class ThreadA 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()+"已经终止!");
}
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/oscar999/archive/2007/08/23/1755759.aspx