轻量级动态线程池才是“王道”?(四)
四、常见问题
1. 项目关闭时,如何保障线程池中任务全部完成
答:借鉴了 Spring 封装的线程池框架。构建动态线程池时,指定 waitForTasksToCompleteOnShutdown 和 awaitTerminationMillis
import cn.hippo4j.core.executor.DynamicThreadPool;
import cn.hippo4j.core.executor.support.ThreadPoolBuilder;
@Bean
@DynamicThreadPool
public ThreadPoolExecutor dynamicThreadPoolExecutor() {
String consumeThreadPoolId = "message-consume";
return ThreadPoolBuilder.builder()
.threadFactory(consumeThreadPoolId)
.waitForTasksToCompleteOnShutdown(true)
.awaitTerminationMillis(5000L)
.dynamicPool()
.build();
}
这两个参数什么意思呢?
- waitForTasksToCompleteOnShutdown:是否在关闭线程池时等待任务完成,这里我们设置 true;
- awaitTerminationMillis:等待任务完成的时间,单位毫秒。
问题很多的小伙伴可能就问了:为啥要有 awaitTerminationMillis 这个参数?直接等待全部任务完成不就行了。
线程池中都是执行很快的任务可能是没问题。但是,如果线程池里面都是耗时的任务呢?
停止项目时等个几分钟甚至更长时间是无法忍受的。这个需要根据大家项目的实际情况评估。
2. 动态线程池是否可以传递上下文参数
可以的,同样是借鉴 Spring 线程池框架。实现 TaskDecorator 接口,并在构建动态线程池时指定。
import cn.hippo4j.core.executor.DynamicThreadPool;
import cn.hippo4j.core.executor.support.ThreadPoolBuilder;
@Bean
@DynamicThreadPool
public ThreadPoolExecutor dynamicThreadPoolExecutor() {
String consumeThreadPoolId = "message-consume";
return ThreadPoolBuilder.builder()
.threadFactory(consumeThreadPoolId)
.waitForTasksToCompleteOnShutdown(true)
.awaitTerminationMillis(5000L)
.taskDecorator(new TaskDecoratorTest.ContextCopyingDecorator())
.dynamicPool()
.build();
}
3. Hippo4j Core 和 Hippo4j Server 转换麻烦么
有些小伙伴最初用的 Hippo4j Core,觉得功能并不满足使用,想要使用 Hippo4j Server,问我如何转换?
其实这里非常简单。从项目上来说:代码无需任何改变,把 Pom 文件中的依赖坐标改下就可以。
其次就是将配置中心里的配置迁移到 Hippo4j 的控制台,将线程池记录创建才出来即可。
五、文末总结
文章介绍了 Hippo4j 新增的一种使用模式:依赖配置中心的轻量动态线程池的实现。
不太好评价 Hippo4j Server 和 Hippo4j Core 的好坏。一个是功能更强大,一个是引入更加轻量,使用上具体如何,交给使用者来评价。
如果项目中使用了 配置中心以及线程池 的话,强烈推荐大家引入到项目中试一试,为项目线上的稳定性多了一份保障。
因为个人能力有限,项目中难免会有考虑不到或待优化的地方,各位小伙伴有兴趣可以提交 PR 修复。
文章转自公众号:龙台的技术笔记