zoukankan      html  css  js  c++  java
  • 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()+"已经终止!");
       }
    }
  • 相关阅读:
    做SQL解析时遇到的问题
    SqlAnalyzer1.00源码
    用于测试SqlAnalyzer1.00的十七个测试用例
    XmlAnalyzer1.00 源码
    用于测试XmlAnalyzer 1.00版的八个测试用例
    JsonAnalyzer2 1.01版
    用于测试 JsonAnalyzer2 1.01版的测试用例
    按照BNF语法重新写就的JsonAnalyzer2
    递归向下解析算术表达式(四)
    允许Sublime编辑器在Ubuntu上输入中文
  • 原文地址:https://www.cnblogs.com/bigbigtree/p/6774479.html
Copyright © 2011-2022 走看看