正确中断java线程

不提倡的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

你可能感兴趣的:(java,多线程,thread,编程,工作)