zoukankan      html  css  js  c++  java
  • 并发编程(七)线程如何优雅地终止

    一、停止线程的几种方法

    • 使用退出标志,使线程正常退出,也就是当 run() 方法完成后线程中止。
    • 使用interrupt()方法中断线程。
    • 使用stop()方法强行终止线程,但是不推荐使用这个方法,该方法已被弃用!!!

    二、方法详解

    使用标志位终止线程

    /**
     * 设置标识位停止线程
     */
    public class MyThreadStop {
    
        //计数
        private static int count = 0;
        //退出标识符
        public static boolean exit = false;
    
    
        /**
         * 核心线程
         */
        public static void main(final String[] arguments) throws InterruptedException {
            Thread t = new Thread(new TestThread());
            t.start();
        }
    
        /**
         * 同步方法
         */
        public static synchronized void countNum() {
            for (int i = 0; i < 100000; i++) {
                if (count >= 500000) {
                    exit = true; //修改标志位,退出线程
                } else {
                    count++;
                    System.out.println(count);
                }
            }
        }
    
        /**
         * 线程实体(实现Runnable接口)
         */
        static class TestThread implements Runnable {
    
            public void run() {
                while (!exit) {//当标识符没设置停止时,一直做参数递增
                    countNum();
                }
            }
        }
    }

    使用interrupt()方法中断线程

    • interrupt() 方法并不像在 for 循环语句中使用 break 语句那样干脆,马上就停止循环。
    • 调用 interrupt() 方法仅仅是在当前线程中打一个停止的标记,并不会立即终止线程。
    • 至于目标线程收到通知后会如何处理,则完全由目标线程自行决定。
    /**
     * interrupt()方法停止线程
     */
    public class MyThreadStop {
    
        //计数器
        private static int count = 0;
    
        /**
         * 核心线程
         */
        public static void main(final String[] arguments) throws InterruptedException {
            Thread t = new Thread(new TestThread());
            t.start();
            //休眠一会儿,然后中断
            t.sleep(200);
            t.interrupt();
        }
    
        /**
         * 同步方法
         */
        public static synchronized void countNum() {
            for (int i = 0; i < 500000; i++) {
                count++;
                System.out.println(count);
            }
        }
    
        /**
         * 线程实体(实现Runnable接口)
         */
        static class TestThread implements Runnable {
            public void run() {
                countNum();
            }
        }
    }

      上面的例子我们发现,好像interrupt方法并没有马上停止线程,还是继续跑完了,这是由于interrupt() 方法仅仅是在当前线程中打一个停止的标记,并不会立即终止线程。 至于目标线程收到通知后会如何处理,则完全由目标线程自行决定。

      我们可以改造一下~

    /**
     * interrupt()方法停止线程
     */
    public class MyThreadStop {
    
        //计数器
        private static int count = 0;
    
        /**
         * 核心线程
         */
        public static void main(final String[] arguments) throws InterruptedException {
            Thread t = new Thread(new TestThread());
            t.start();
            //休眠一会儿,然后中断
            t.sleep(200);
            t.interrupt();
        }
    
    
        /**
         * 线程实体(实现Runnable接口)
         */
        static class TestThread implements Runnable {
            public void run() {
                for (int i = 0; i < 500000; i++) {
                    //判断线程是否被通知中断
                    if (Thread.currentThread().isInterrupted()) {
                        //处理中断逻辑
                        break;
                    }
                    count++;
                    System.out.println(count);
                }
            }
        }
    }

      可以发现,在加入中断判断以后,线程停止了工作

      PS:当线程被 sleep() 休眠时,如果被中断,就会抛出一个 InterruptedException异常。

      PS:Thread.sleep() 方法由于中断而抛出的异常,是会清除中断标记的,线程后面的代码会继续执行

    stop()方法

      stop()方法停止线程的方式相当粗暴,直接停止线程工作,相当不安全,虽然现在已经弃用,还是简单的了解一下吧。

      为什么弃用stop:

    • 调用 stop() 方法会立刻停止 run() 方法中剩余的全部工作,包括在 catch 或 finally 语句中的,并抛出ThreadDeath异常(通常情况下此异常不需要显示的捕获),因此可能会导致一些清理性的工作的得不到完成,如文件,数据库等的关闭。
    • 调用 stop() 方法会立即释放该线程所持有的所有的锁,导致数据得不到同步,出现数据不一致的问题。

    好文推荐:

  • 相关阅读:
    Asp.NET Core+ABP框架+IdentityServer4+MySQL+Ext JS之验证码
    ABP前端使用阿里云angular2 UI框架NG-ZORRO分享
    ASP.NET Core之跨平台的实时性能监控(2.健康检查)
    应用程序的8个关键性能指标以及测量方法
    ASP.NET Core之跨平台的实时性能监控
    浅析Entity Framework Core2.0的日志记录与动态查询条件
    开发短网址平台的思路
    Nginx解决错误413 Request Entity Too Large
    配置Nginx实现负载均衡
    Windows下Nginx的安装及使用方法入门
  • 原文地址:https://www.cnblogs.com/riches/p/12023692.html
Copyright © 2011-2022 走看看