前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >八股文:如有优雅关闭(Graceful Shutdown)Java的线程池ExecutorService

八股文:如有优雅关闭(Graceful Shutdown)Java的线程池ExecutorService

作者头像
崔认知
发布2024-06-17 13:42:08
4340
发布2024-06-17 13:42:08
举报
文章被收录于专栏:nobody

优雅地关闭线程池是一个涉及资源管理和代码健壮性的重要问题。在Java中,可以使用ExecutorService来创建和管理线程池,并使用其提供的方法来优雅地关闭线程池。以下是一些建议的步骤和注意事项:

1、调用shutdown()方法拒绝新提交的任务,已提交的任务不受影响。

调用shutdown()后,已提交的任务会继续执行,但线程池不再接收新任务。如果调用shutdown()时线程池已经关闭,那么这个方法不会有任何效果。

调用shutdown()后,不会阻塞等待已提交的任务执行完成,如果需要阻塞等待,需要调用awaitTermination()方法。

2、调用awaitTermination方法等待已提交任务完成。

在调用shutdown()之后,可以使用awaitTermination(long timeout, TimeUnit unit)方法来等待线程池中的所有任务都完成执行。

这个方法会阻塞当前线程,直到所有任务都完成执行、超时发生,或者当前线程被中断,以先发生者为准。

如果在超时时间内所有任务都完成了,那么这个方法会返回true;否则返回false

3、处理未完成的任务,必要时调用shutdownNow()。

调用 awaitTermination(long timeout, TimeUnit unit)方法来等待线程池中的所有任务都完成执行,如果在超时时间内所有任务都完成了,那么这个方法会返回true;否则返回false,这时我们可以调用shutdownNow(),强制停止未执行完的任务。

调用shutdownNow()也不会阻塞等待强制停止未完成的任务,所以可以再次使用awaitTermination(long timeout, TimeUnit unit)方法等待。

4、异常处理

在关闭线程池的过程中,需要注意捕获和处理可能出现的异常,以确保程序的健壮性。

5、代码示例

dubbo3源码:

代码语言:javascript
复制
org.apache.dubbo.common.utils.ExecutorUtil#gracefulShutdown
代码语言:javascript
复制
public static void gracefulShutdown(Executor executor, int timeout) {
        if (!(executor instanceof ExecutorService) || isTerminated(executor)) {
            return;
        }
        final ExecutorService es = (ExecutorService) executor;
        try {
            // Disable new tasks from being submitted
            es.shutdown();
        } catch (SecurityException | NullPointerException ex2) {
            return;
        }
        try {
            // Wait a while for existing tasks to terminate
            if (!es.awaitTermination(timeout, TimeUnit.MILLISECONDS)) {
                es.shutdownNow();
            }
        } catch (InterruptedException ex) {
            es.shutdownNow();
            Thread.currentThread().interrupt();
        }
        if (!isTerminated(es)) {
            newThreadToCloseExecutor(es);
        }
    }

rocketmq5.0.0源码:

代码语言:javascript
复制
org.apache.rocketmq.common.utils.ThreadUtils#shutdownGracefully(java.util.concurrent.ExecutorService, long, java.util.concurrent.TimeUnit)
代码语言:javascript
复制
public static void shutdownGracefully(ExecutorService executor, long timeout, TimeUnit timeUnit) {
        // Disable new tasks from being submitted.
        executor.shutdown();
        try {
            // Wait a while for existing tasks to terminate.
            if (!executor.awaitTermination(timeout, timeUnit)) {
                executor.shutdownNow();
                // Wait a while for tasks to respond to being cancelled.
                if (!executor.awaitTermination(timeout, timeUnit)) {
                    LOGGER.warn(String.format("%s didn't terminate!", executor));
                }
            }
        } catch (InterruptedException ie) {
            // (Re-)Cancel if current thread also interrupted.
            executor.shutdownNow();
            // Preserve interrupt status.
            Thread.currentThread().interrupt();
        }
    }
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 认知科技技术团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档