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()+"已经终止!");
       }
    }
  • 相关阅读:
    【转载】使用Jquery操作Cookie对象
    PHP实现双向链表、栈
    Mysql触发器、模糊查找、存储过程、内置函数
    List、Set、Map、数组之间各种转换
    Android -- 压缩与解压文件
    Android -- 动态添加布局
    Android -- Service绑定解绑和aidl
    Android -- 图像处理(信息量超大)
    Android -- 利用Broadcast开启Service
    Android -- Service的开启关闭与生命周期
  • 原文地址:https://www.cnblogs.com/bigbigtree/p/6774479.html
Copyright © 2011-2022 走看看