如何终止一个线程

2020-12-09 19:08发布

线程终止

一、不正确的线程终止--Stop

Stop:终止线程,并且清除监控器锁的信息,但是可能导致线程安全问题,JDK已经废弃使用。

Destroy:JDk未实现该方法

package com.offcn;

public class StopThread extends Thread {

   private int i=0,j=0;
   @Override
   public void run() {
       synchronized (this){
           ++i;
           try {
               Thread.sleep(10000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           ++j;
       }
   }

   public void print(){
       System.out.println("i="+i+" j="+j);
   }
}


测试停止线程:

package com.offcn;

public class Demo3 {
   public static void main(String[] args) throws InterruptedException {
       StopThread thread = new StopThread();
       thread.start();
       //休眠1秒,确保i变量自增成功
       Thread.sleep(1000);

       //中止线程
       thread.stop();

       //判断线程是否终止
       while (thread.isAlive()){

       }

       //打印变量
       thread.print();

   }
}

测试运行:

理想的输出结果 i=0 j=0

实际的输出结果 i=1 j=0

stop没有保证同步代码块里面数据的一致性,破坏了线程安全

二、正确的线程终止--interrupt

如果目标线程在调用Object class的wait()、wait(long)或者wait(long,int)方法、join()、join(long,int)或sleep(long,int)方法时被阻塞,那么Interrupt会生效,该线程的中断状态将被清除,抛出InterruptedException异常。

如果目标线程是被I/O或者NIO的Channel所阻塞,同样,I/O操作会被中断或者返回特殊异常值。达到终止线程的目的。

如果以上条件都不满足,则会设置此线程的中断状态。


对于Demo3中的实例,stop改成interrupt

package com.offcn;

public class Demo3 {
   public static void main(String[] args) throws InterruptedException {
       StopThread thread = new StopThread();
       thread.start();
       //休眠1秒,确保i变量自增成功
       Thread.sleep(1000);

       //中止线程
      // thread.stop();
       //建议使用
       thread.interrupt();

       //判断线程是否终止
       while (thread.isAlive()){

       }

       //打印变量
       thread.print();

   }
}


运行输出: i=1 j=1 ,数据一致


三、正确的线程终止--标志位

代码逻辑中,增加一个判断,用来控制线程执行的中止。

代码如下Demo4

package com.offcn;

public class Demo4 extends Thread {
   //设置标志位,控制线程是否可以允许
   public volatile static boolean flag=true;

   public static void main(String[] args) throws InterruptedException {
       new Thread(()->{
           try {
               while (flag){
                   System.out.println("运行中");
                   Thread.sleep(1000L);
               }
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }).start();

       //3秒钟后把标准位改成false
       Thread.sleep(3000L);
       flag=false;
       System.out.println("程序运行结束");

   }
}