关键是在newthread()方法中显式设置带业务标识和序号的线程名,如order-notify-1,并配置守护态、优先级与异常处理器,所有线程池均需注入独立的threadfactory实例。

关键是在 newThread() 方法里主动设置线程名,并带上业务上下文,而不是依赖默认编号。
命名格式要带业务标识和序号
线程名不能只是“pool-1-thread-1”这种无意义编号。推荐用 ${模块}-${场景}-${序号} 格式,比如 order-notify-1、payment-retry-3、inventory-deduct-io-2。
- 模块和场景体现业务归属,便于日志过滤和问题定位
- 序号用
AtomicInteger递增,保证同一工厂下不重复 - 避免空格、斜杠、控制字符,某些监控工具(如 Arthas)会解析失败
- 别用 UUID 或随机数——不可预测、难 grep、无序号语义
必须在 newThread() 中显式 setName()
线程池复用线程,名字只在创建时生效;任务执行中调用 Thread.currentThread().setName() 不起作用,也不会更新线程池记录的名称。
- 构造
Thread对象时,必须传入名称,或立即调用t.setName(...) - 不要省略这一步,JVM 不会自动补全
- 命名逻辑写在
newThread()里,不是在线程启动后或任务 run() 中
统一设置守护态、优先级与异常处理器
光设名字不够,还要让线程行为可控、可观测。
-
t.setDaemon(false):多数业务线程应是非守护的,防止 JVM 提前退出 -
t.setPriority(Thread.NORM_PRIORITY):慎调高优先级,低于默认值更安全 -
t.setUncaughtExceptionHandler(...):捕获未处理异常,避免静默失败 - 线程组建议复用当前线程组:
Thread.currentThread().getThreadGroup(),避免脱离容器管理
不同线程池都要注入同一套工厂
只要线程池构造支持传 ThreadFactory,就能统一规范。
-
ThreadPoolExecutor构造器直接传入 -
Executors.newFixedThreadPool(4, factory)或newCachedThreadPool(factory) - Spring 的
ThreadPoolTaskExecutor调用setThreadFactory() - 注意别复用单例工厂实例——尤其 Spring 中
@Bean默认是 singleton,不同线程池要用不同前缀的实例
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











