Java——安全地停止线程

错误用例

下面用例中,一个正在sleep的线程,在调用interrupt后,wait方法检查到isInterrupted()为true,抛出异常, 而catch到异常后没有处理。一个抛出了InterruptedException的线程的在调用interrupt后状态马上就会被置为非中断状态。如果catch语句没有处理异常,则下一 次循环中isInterrupted()为false,线程会继续执行,程序无法正常退出。

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SparkStreamThread implements Runnable {

    public void stopStream() {
        this.log.warn("Stop Stream!!");
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "将要运行...");
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println(Thread.currentThread().getName() + "运行中");
            try {
                Thread.sleep(400);
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName() + "从阻塞中退出...");
                System.out.println("this.isInterrupted()=" + Thread.currentThread().isInterrupted());
            }
        }
        System.out.println(Thread.currentThread().getName() + "已经终止!");
    }

    public static void main(String argv[]) throws InterruptedException {
        Thread ta = new Thread(new SparkStreamThread());
        ta.start();
        Thread.sleep(2000);
        System.out.println(ta.getName() + "正在被中断...");
        ta.interrupt();
        System.out.println("ta.isInterrupted()=" + ta.isInterrupted());
    }
}

 

正确用例1,异常捕获后终止线程

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SparkStreamThread implements Runnable {

    public void stopStream() {
        this.log.warn("Stop Stream!!");
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "将要运行...");
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println(Thread.currentThread().getName() + "运行中");
            try {
                Thread.sleep(400);
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName() + "从阻塞中退出...");
                Thread.currentThread().interrupt();
                System.out.println("this.isInterrupted()=" + Thread.currentThread().isInterrupted());
            }
        }
        System.out.println(Thread.currentThread().getName() + "已经终止!");
    }

    public static void main(String argv[]) throws InterruptedException {
        Thread ta = new Thread(new SparkStreamThread());
        ta.start();
        Thread.sleep(2000);
        System.out.println(ta.getName() + "正在被中断...");
        ta.interrupt();
        System.out.println("ta.isInterrupted()=" + ta.isInterrupted());
    }
}

 

 

正确用例2, 使用变量,double check,二次检查

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()+"已经终止!");
   }
}

 

posted @ 2017-04-27 15:27  bigbigtree  阅读(485)  评论(0编辑  收藏  举报