zoukankan      html  css  js  c++  java
  • dubbo如何关闭一个线程池的?

    public static void gracefulShutdown(Executor executor, int timeout) {
            if (!(executor instanceof ExecutorService) || isShutdown(executor)) {
                return;
            }
            final ExecutorService es = (ExecutorService) executor;
            try {
                es.shutdown(); // Disable new tasks from being submitted
            } catch (SecurityException ex2) {
                return;
            } catch (NullPointerException ex2) {
                return;
            }
            try {
                if (!es.awaitTermination(timeout, TimeUnit.MILLISECONDS)) {
                    es.shutdownNow();
                }
            } catch (InterruptedException ex) {
                es.shutdownNow();
                Thread.currentThread().interrupt();
            }
            if (!isShutdown(es)) {
                newThreadToCloseExecutor(es);
            }
        }
    

     根据注释,shutdown方法只是用来停止接收新的task,但是不能保证老的task是否已经停止。如果抛出SecurityException,那么说明调用者是不能直接关闭这个线程池的。

       如果要确保老的任务也停止的话,那么需要调用awaitTermination阻塞等待关闭的结果。

    /**
         * Blocks until all tasks have completed execution after a shutdown
         * request, or the timeout occurs, or the current thread is
         * interrupted, whichever happens first.
         *
         * @param timeout the maximum time to wait
         * @param unit the time unit of the timeout argument
         * @return {@code true} if this executor terminated and
         *         {@code false} if the timeout elapsed before termination
         * @throws InterruptedException if interrupted while waiting
         */
        boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException;
    

      如果返回结果是false,那么说明是超时返回,直接调用shutdownNow,这个方法尝试关闭你所有的线程,但是依然无法保证所有的线程都能够真正关闭,因为有些线程可能会忽略掉interrupt方法,如果需要知道最终的结果,跟shutdown方法一样,需要调用awaitTermination阻塞等待结果。

      interrupt这个到底是啥?shutdownnow的时候也try了一下InterruptedException

          如果一个线程处于running状态,对他调用interrupt,那么这个线程的状态继续运行,只是这个线程的标记位interrupted=true,也就是说无法通过中断方法终止一个线程,如果有业务需要,可以让线程在循环里面check这个状态位。

        如果一个线程阻塞状态(wait方法阻塞、sleep方法阻塞),那么对这个线程调用interrupt方法,这个线程就会从阻塞状态返回过来,并且抛出InterruptedException异常,更重要的是interrupted=false,也就是说这种情况下不能依赖这个标志位了,如果业务上真有中断线程的需要的话,可以catch这个异常,增加一个新的标志位、check这个标志位作为是否结束线程的标志。

      InterruptedException意味着阻塞状态的线程被interrupt了,为了不直接吞掉这个异常,把当前线程设置了标志位,供外面查询Thread.currentThread().interrupt()。

     最后如果试了shutdown和shutdownnow都不行的话,那么生成了一个新的线程来关闭线程池,不能阻塞主线程太久。newThreadToCloseExecutor具体代码:

    private static void newThreadToCloseExecutor(final ExecutorService es) {
            if (!isShutdown(es)) {
                shutdownExecutor.execute(new Runnable() {
                    public void run() {
                        try {
                            for (int i = 0; i < 1000; i++) {
                                es.shutdownNow();
                                if (es.awaitTermination(10, TimeUnit.MILLISECONDS)) {
                                    break;
                                }
                            }
                        } catch (InterruptedException ex) {
                            Thread.currentThread().interrupt();
                        } catch (Throwable e) {
                            logger.warn(e.getMessage(), e);
                        }
                    }
                });
            }
        }
    

      让一个新的线程多次轮训shutdownnow,然后await结果,如果await返回true,那么线程池全部终止。否则继续shutdownnow,吞掉着其中发生的InterruptedException异常。

  • 相关阅读:
    iOS 'The sandbox is not sync with the Podfile.lock错误
    iOS __strong __weak @Strongify @Weakify
    iOS Debug日志 viewhierarchy调试笔记
    网易163 docker镜像
    mysql 双主复制 windows10
    (转) MySQL常用Json函数
    springboot 不同环境读取不同配置
    Mysql Cluster7.5.6 windows10 部署安装
    SourceTree 免登录跳过初始设置
    Java Object to Class
  • 原文地址:https://www.cnblogs.com/notlate/p/10204834.html
Copyright © 2011-2022 走看看