java线程池必须通过自定义threadfactory在newthread()中显式设置名称、线程组、守护态、优先级及异常处理器,命名格式为{模块}-{场景}-{序号},序号用atomicinteger递增,总长≤32字符,工厂需独占实例且无耗时操作。

Java 线程池必须通过自定义 ThreadFactory 在 newThread() 中显式调用 t.setName() 才能规范线程名称,同时复用当前线程组、禁用守护态、统一异常处理——这些不能靠事后修改或默认行为补救。
命名要带业务上下文和唯一序号
线程名格式推荐 {模块}-{场景}-{序号},例如 order-processor-1、cache-loader-3:
- 前缀全小写,用短横线分隔,禁用空格、斜杠、中文、控制字符
- 序号必须用
AtomicInteger递增生成,不依赖时间戳、UUID 或随机数 - 总长度控制在 32 字符内,避免 Arthas、JFR 等工具解析异常
- 可选加用途后缀,如
-io或-cpu,便于监控分类
线程组和守护状态必须显式设置
不要沿用默认逻辑,关键属性需在 newThread() 内一步到位:
- 线程组统一设为
Thread.currentThread().getThreadGroup(),不新建,防止绕过 Spring 容器管理 - 业务线程一律
t.setDaemon(false),避免 JVM 主线程退出时被静默终止 - 优先级保持
Thread.NORM_PRIORITY(值为 5),除非有强实时要求,否则不建议调整
异常处理器和复用安全要点
未捕获异常若只打到 System.err,线上基本等于丢失:
- 务必调用
t.setUncaughtExceptionHandler(),把异常写入业务日志,并带上thread.getName()和当前 traceId - 工厂实例不能全局单例(尤其 Spring 中),每个线程池应独占一个新实例,避免序号冲突或状态污染
- 工厂内部禁止耗时操作(如锁、sleep、IO),否则会阻塞
prestartCoreThread()等初始化流程
主流线程池都支持注入,验证要主动触发
无论哪种创建方式,只要传入自定义工厂就生效:
-
Executors.newFixedThreadPool(4, factory)完全可用 -
ThreadPoolExecutor构造器第 5 个参数即为ThreadFactory - Spring 的
ThreadPoolTaskExecutor调用setThreadFactory()注入 - 验证是否生效:调用
executor.prestartAllCoreThreads()强制创建核心线程,再查线程 dump 或 JConsole 确认名称
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











