美文网首页
ExecutorService shutdown()和shutd

ExecutorService shutdown()和shutd

作者: zhong0316 | 来源:发表于2019-02-22 09:30 被阅读25次

    ExecutorService是我们经常使用的线程池,当我们使用完线程池后,需要关闭线程池。ExecutorService的shutdown()和shutdownNow()方法都可以用来关闭线程池,那么他们有什么区别呢?

    废话不多说,直接查看源码,shutdown方法:

    /**
          * Initiates an orderly shutdown in which previously submitted
          * tasks are executed, but no new tasks will be accepted.
          * Invocation has no additional effect if already shut down.
          *
          * <p>This method does not wait for previously submitted tasks to
          * complete execution.  Use {@link #awaitTermination awaitTermination}
          * to do that.
          *
          * @throws SecurityException if a security manager exists and
          *         shutting down this ExecutorService may manipulate
          *         threads that the caller is not permitted to modify
          *         because it does not hold {@link
          *         java.lang.RuntimePermission}{@code ("modifyThread")},
          *         or the security manager's {@code checkAccess} method
          *         denies access.
          */
         void shutdown();
    

    当我们调用shutdown()方法后,线程池会等待我们已经提交的任务执行完成。但是此时线程池不再接受新的任务,如果我们再向线程池中提交任务,将会抛RejectedExecutionException异常。如果线程池的shutdown()方法已经调用过,重复调用没有额外效应。注意,当我们调用shutdown()方法后,会立即从该方法中返回而不会阻塞等待线程池关闭再返回,如果希望阻塞等待可以调用awaitTermination()方法。

    再看shutdownNow()方法:

    /**
         * Attempts to stop all actively executing tasks, halts the
         * processing of waiting tasks, and returns a list of the tasks
         * that were awaiting execution.
         *
         * <p>This method does not wait for actively executing tasks to
         * terminate.  Use {@link #awaitTermination awaitTermination} to
         * do that.
         *
         * <p>There are no guarantees beyond best-effort attempts to stop
         * processing actively executing tasks.  For example, typical
         * implementations will cancel via {@link Thread#interrupt}, so any
         * task that fails to respond to interrupts may never terminate.
         *
         * @return list of tasks that never commenced execution
         * @throws SecurityException if a security manager exists and
         *         shutting down this ExecutorService may manipulate
         *         threads that the caller is not permitted to modify
         *         because it does not hold {@link
         *         java.lang.RuntimePermission}{@code ("modifyThread")},
         *         or the security manager's {@code checkAccess} method
         *         denies access.
         */
        List<Runnable> shutdownNow();
    

    首先shutdownNow()方法和shutdown()方法一样,当我们调用了shutdownNow()方法后,调用线程立马从该方法返回,而不会阻塞等待。这也算shutdownNow()和shutdown()方法的一个相同点。与shutdown()方法不同的是shutdownNow()方法调用后,线程池会通过调用worker线程的interrupt方法尽最大努力(best-effort)去"终止"已经运行的任务。
    而对于那些在堵塞队列中等待执行的任务,线程池并不会再去执行这些任务,而是直接返回这些等待执行的任务,也就是该方法的返回值。
    值得注意的是,当我们调用一个线程的interrupt()方法后(前提是caller线程有权限,否则抛异常),该线程并不一定会立马退出:

    1. 如果线程处于被阻塞状态(例如处于sleep, wait, join 等状态),那么线程立即退出被阻塞状态,并抛出一个InterruptedException异常。
    2. 如果线程处于正常的工作状态,该方法只会设置线程的一个状态位为true而已,线程会继续执行不受影响。如果想停止线程运行可以在任务中检查当前线程的状态(Thread.isInterrupted())自己实现停止逻辑。

    相关文章

      网友评论

          本文标题:ExecutorService shutdown()和shutd

          本文链接:https://www.haomeiwen.com/subject/pmdsyqtx.html