创建裸线程的危害,以及如何管理线程的优雅退出

裸线程的危害

Thread t = new Thread(load);
t.setDaemon(false);
t.start();

创建裸的非守护线程,kill -15 pid 应用停止的时候,线程一直在跑,应用是停止不了的,只能kill -9 pid,因为jvm会发现仍然有非守护线程在运行中,JVM 只有在“所有非守护线程结束”后才会退出。
而创建守护线程也有问题(t.setDaemon(true)),如果里边是重要的业务逻辑,那么有可能没执行完毕就被干掉了,当只剩守护线程时,JVM 会直接退出,不保证守护线程执行完成。

好的实践方式:线程池 + Spring管理

不要直接 new Thread,而应使用线程池,并交由 Spring 管理生命周期比较好的实践方式,如下例子:

@Bean(destroyMethod = "shutdown")
public ScheduledExecutorService myExecutor() {
    return Executors.newSingleThreadScheduledExecutor(
            r -> new Thread(r, "my-thread")
    );
}

myExecutor.scheduleWithFixedDelay(new Runnable() {
    @Override
    public void run() {
            try {
                //业务逻辑
            } catch (Exception e) {
                LOG.error("Error: ", e);
            }
    }
}, 0, 30, TimeUnit.SECONDS);

对线程池myExecutor添加注解@Bean(destroyMethod = "shutdown"),Spring会在应用停止的时候回调ScheduledExecutorService.shutdown()方法,实现优雅关闭(与之相对的shutdownNow()是立即关闭)

慎用kill -9

  • kill -15(SIGTERM): → 触发 JVM shutdown hook ,Spring 开始优雅关闭(Context.close)。 如果有“线程不退出(非守护 + 死循环)”这种情况,JVM 会一直等。
  • kill -9(SIGKILL): → 强制终止,不执行 shutdown hook,所有优雅关闭机制失效。
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容