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