正确中断java线程

不提倡的stop()方法
臭名昭著的stop()停止线程的方法已不提倡使用了,原因是什么呢?
 当在一个线程对象上调用stop()方法时,这个线程对象所运行的线程就会立即停止,并抛出特殊的ThreadDeath()异常。这里的“立即”因为太“立即”了,
假如一个线程正在执行:
synchronized void {
x = 3;
y = 4;
}

  由于方法是同步的,多个线程访问时总能保证x,y被同时赋值,而如果一个线程正在执行到x = 3;时,被调用了 stop()方法,即使在同步块中,它也干脆地stop了,这样就产生了不完整的残废数据。而多线程编程中最最基础的条件要保证数据的完整性,所以请忘记 线程的stop方法,以后我们再也不要说“停止线程”了。

   如何才能“结束”一个线程?

interupt()中断线程

一个线程从运行到真正的结束,应该有三个阶段:
  1. 正常运行.
  2. 处理结束前的工作,也就是准备结束.
  3. 结束退出.
那么如何让一个线程结束呢?既然不能调用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()
+"已经终止!");
   }

}




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