java线程池优雅关闭

Java】如何优雅关闭线程池 想要优雅关闭线程池,首先要理解线程中断的含义。其次,关闭线程池有两种方式:shutdown() 和 shutdownNow(),二者最大的区别是 shutdown() 只是把空闲的 woker 置为中断,不影响正在运行的woker,并且会继续把待执行的任务给处理完。shutdonwNow() 则是把所有的 woker 都置为中断,待执行的任务全部抽出并返回,日常工作中更多是使用 shutdown()。 阅读详情

案例

通过一个例子理解线程池优雅关闭的过程

@ToString
public class Task implements Runnable {

    int index;

    public Task(int index) {
        this.index = index;
    }

    @Override
    public void run() {
        System.out.println("开始执行 " + index);
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            System.out.println("任务被中断 " + index);
            return;
        }
        System.out.println("执行完成 " + index);
    }
}
public class ShutdownDemo {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        for (int i = 0; i < 10; i++) {
            System.out.println("进入循环 " + i);
            if (i == 5) {
                executorService.shutdown();
            }
            try {
                executorService.execute(new Task(i));
            } catch (RejectedExecutionException e) {
                System.out.println("线程池关闭,拒绝执行 " + i);
            }
        }
        try {
            System.out.println("main 等待线程池关闭");
            boolean isStop = executorService.awaitTermination(2, TimeUnit.SECONDS);
            System.out.println("main 第一次等待线程池关闭结果 " + isStop);
            if (!isStop) {
                System.out.println("main 尝试停止正在执行的任务");
                List<Runnable> runnables = executorService.shutdownNow();
                System.out.println("main 等待中的任务已全部移除 " + runnables);
                isStop = executorService.awaitTermination(2, TimeUnit.SECONDS);
                System.out.println("main 第二次等待线程池关闭结果 " + isStop);
                if (!isStop) {
                    System.out.println("线程池终止失败");
                }
            }
        } catch (InterruptedException e) {
            System.out.println("main err " + e.getMessage());
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
}

说明

简单说一下代码:

  1. 创建了2个线程的线程池
  2. 尝试用这个线程池执行10次任务(Task)
  3. 在循环i=5时,关闭线程池,所以i从5到9都会被拒绝执行,执行中和等待中的任务为0-4
  4. main线程中等待2s,因为每个任务要休眠2s,并且线程池只有2个线程,此时应该有任务在等待队列中
  5. main线程中尝试中断线程池中正在执行的任务,并且返回等待中的任务
  6. main线程再次等待2s,再确认线程池是否关闭成功

执行代码,输出如下

进入循环 0
进入循环 1
进入循环 2
进入循环 3
进入循环 4
进入循环 5
开始执行 0
开始执行 1
线程池关闭,拒绝执行 5
进入循环 6
线程池关闭,拒绝执行 6
进入循环 7
线程池关闭,拒绝执行 7
进入循环 8
线程池关闭,拒绝执行 8
进入循环 9
线程池关闭,拒绝执行 9
main 等待线程池关闭
执行完成 1
执行完成 0
开始执行 2
开始执行 3
main 第一次等待线程池关闭结果 false
main 尝试停止正在执行的任务
任务被中断 2
任务被中断 3
main 等待中的任务已全部移除 [Task(index=4)]
main 第二次等待线程池关闭结果 true

参考

jdk17 docs

如何优雅关闭Java线程池 如何优雅关闭Java线程池 - 清泉^_^ - 博客园 面试中经常会问到,创建一个线程池需要哪些参数啊,线程池的工作原理啊,却很少会问到线程池如何安全关闭的。 也正是因为大家不是很关注这块,即便是工作三四年的人,也会有因为线程池关闭不合理,导致应用无法正常stop的情况,还有出现一些报错的问题。 本篇就以ThreadPoolExecutor为例,来介绍下如何优雅关闭线程池。 01 线程中断 在介绍线程池关闭之前,先介绍下Thread的interrupt。 在程序中,我们是不能随便中断一个 阅读详情

相关推荐

线程池优雅关闭探究

线程池优雅停机方案 简介 在开发中使用线程池去执行异步任务是比较普遍的操作,然而虽然有些异步操作我们并不十分要求可靠性和实时性,但总归业务还是需要的。如果在每次的服务发版过程中,我们不去介入线程池的停机逻辑,那么很有可能就会造成线程池中队列的任务还未执行完成,自然就会造成数据的丢失。 探究 注意,本文所有前提是对进程进行下线时使用的是kill 我们知道Spring已经实现了自己的优雅停机方案,详细请参考org.springframework.context.support.AbstractApplicati

yichen0429的博客 3055

线程池如何优雅关闭

介绍了线程池如何优雅关闭,欢迎阅读斧正。

格物致知,知行合一。 1888

java】如何优雅的停止线程?

尝试去关闭线程volatile 关键字:中断标记:线程池相关方法,会去尝试关闭线程池中正在运行的线程。上面这些方法都是优雅关闭线程的方法,他们都是尝试去关闭线程而不是强制关闭线程。

2401_82656016的博客 1856

JAVA线程池如何优雅关闭

JAVA线程池如何优雅关闭 Effective JAVA 第三版并发部分提起了线程池优雅关闭的问题,意识到之前的线程关闭知识还不完善。讨论如下: 1.shutdown() 基本意思是:启动有序关闭,其中先前提交的任务将被执行关闭,但不会接受任何新任务。 如果已经关闭,调用没有额外的作用。 此方法不等待以前提交的任务完成执行。 使用awaitTermination做到这一点。 shutdown只负责任务关闭,不负责任务是否执行完毕。比如有线程往数据库写数据,当线程池任务shutdown时,数据未完全写入

qq_41534553的博客 564

java优雅关闭线程池

如何优雅关闭线程池 记录下来,以后忘记了就看一下。 根据ExecutorService JavaDoc中的示例方法优雅关闭线程池并了解其中的工作原理,不深入探究。 /** * 优雅关闭线程池 * 按照ExecutorService JavaDoc示例代码编写的Graceful Shutdown方法. * 先使用shutdown, 停止接收新任务并尝试完成所...

xiangxiaotian666的博客 598

java 关闭线程池_如何优雅关闭Java线程池

以上就是shutdownNow方法的执行逻辑:将线程池状态修改为STOP,然后调用线程池里的所有线程的interrupt方法。调用shutdownNow后,线程池里的线程会做如何反应呢?那就要看,线程池里线程正在执行的代码逻辑了。其在线程池的runWorker方法里(对线程池的执行原理不了解的,请看之前的文章),其代码如下:正常情况下,线程池里的线程,就是在这个while循环里不停地执行。其中代码...

weixin_36244175的博客 335

java如何关闭线程池_如何优雅关闭Java线程池

⾯试中经常会问到,创建⼀个线程池需要哪些参数、线程池的工作原理,却很少会问到线程池如何安全关闭的。也正是因为⼤家不是很关注这块,即便是⼯作三四年的⼈,也会有因为线程池关闭不合理,导致应用⽆法正常stop的情况,还有出现⼀些报错的问题。本篇就以ThreadPoolExecutor为例例,来介绍下如何优雅关闭线程池。线程中断在介绍线程池关闭之前,先介绍下Thread的interrupt。在程序中,我...

weixin_35029295的博客 897

java如何关闭多个线程池_如何优雅关闭Java线程池

本篇就以ThreadPoolExecutor为例,来介绍下如何优雅关闭线程池。01 线程中断在介绍线程池关闭之前,先介绍下Thread的interrupt。在程序中,我们是不能随便中断一个线程的,因为这是极其不安全的操作,我们无法知道这个线程正运行在什么状态,它可能持有某把锁,强行中断可能导致锁不能释放的问题;或者线程可能在操作数据库,强行中断导致数据不一致混乱的问题。正因此,JAVA里将Thr...

weixin_32484541的博客 254

java 线程池 关闭线程池_如何优雅关闭Java线程池

以上就是shutdownNow方法的执行逻辑:将线程池状态修改为STOP,然后调用线程池里的所有线程的interrupt方法。调用shutdownNow后,线程池里的线程会做如何反应呢?那就要看,线程池里线程正在执行的代码逻辑了。其在线程池的runWorker方法里(对线程池的执行原理不了解的,请看之前的文章),其代码如下:正常情况下,线程池里的线程,就是在这个while循环里不停地执行。其中代码...

weixin_29206669的博客 515

java 如何优雅关闭线程池

转自: https://blog.csdn.net/yelvgou9995/article/details/80761005   ⾯试中经常会问到,创建⼀个线程池需要哪些参数、线程池的工作原理,却很少会问到线程池如何安全关闭的。 也正是因为⼤家不是很关注这块,即便是⼯作三四年的⼈,也会有因为线程池关闭不合理,导致应用⽆法正常stop的情况,还有出现⼀些报错的问题。 本篇就以ThreadPo...

hemeinvyiqiluoben的专栏 9124

7.Java并发编程—掌握线程池的标准创建方式和优雅关闭技巧,提升任务调度效率

本文详细介绍了线程池的标准创建方式和参数设置,包括核心线程数、最大线程数和阻塞队列的选择。同时,探讨了向线程池提交任务的两种方式:execute()和submit()。通过案例演示,展示了如何使用这两种方法来提交任务。此外,文章还介绍了线程池的任务调度流程,包括ThreadFactory的源码解析和自定义简单线程工厂的实现方式。对于任务阻塞队列和线程池的拒绝策略也进行了解析,并提供了优雅关闭线程池的方法。最后,通过测试案例验证了限时等待和等待全部任务执行完毕两种关闭线程池的技巧,帮助读者更好地掌握线程池

q1372302825的博客 1196

优雅关闭Java线程池,这样做才是yyds

戳上方蓝字“Java笔记虾”关注我1背景某年某月某日,和我的卧龙同事聊一个需求,说是有个数据查询的功能,因为涉及到多个第三方接口调用,想用线程池并行来做。很正常的一个方案,但是上线后发现,每次服务发布的时候,这个数据查询的功能就会挂掉,后来发现是线程池没有做好关闭,这里总结一下。关键字:线程池;shutdown;shutdownNow;interrupt2线程中断 interrupt先补一补基础的...

Java笔记虾 876

别再乱用shutdown了!Java线程池优雅关闭的3种实战场景与避坑指南

本文深入探讨Java线程池优雅关闭的3种实战场景与避坑指南,涵盖微服务下线、定时任务和高并发服务的线程池管理。通过`shutdown`、`shutdownNow`和`awaitTermination`等方法的合理组合,确保任务安全终止,避免数据丢失和系统崩溃。文章还提供了Spring集成、Quartz调度和补偿机制等实用方案,帮助开发者实现高效、安全的线程池关闭

weixin_30457465的博客 275
上一篇: go单元测试 mock 构造仿对象
下一篇: @Scheduled异步执行-自定义线程池
hbqst
博客等级 码龄7年 105粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值