@Slf4j
@Configuration
public class ThreadPoolConfig {
@Bean
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
int i = Runtime.getRuntime().availableProcessors();
// 自定义ThreadFactory
// executor.setThreadFactory(threadFactory());
// 核心线程数目
executor.setCorePoolSize(i * 2);
// 指定最大线程数
executor.setMaxPoolSize(i * 2);
// 队列中最大的数目
executor.setQueueCapacity(i * 2 * 10);
// 线程名称前缀
executor.setThreadNamePrefix("ThreadPoolTaskExecutor-");
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// caller-run-policy:不在新线程中执行任务,而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 当调度器shutdown被调用时等待当前被调度的任务完成
executor.setWaitForTasksToCompleteOnShutdown(true);
// 线程空闲后的最大存活时间
executor.setKeepAliveSeconds(60);
// 设置线程装饰器
executor.setTaskDecorator(runnable -> {
// 获取主线程中的请求信息(我们的用户信息也放在里面)
RequestAttributes attributes = RequestContextHolder.currentRequestAttributes();
return () -> {
try {
// 将主线程的请求信息,设置到子线程中
RequestContextHolder.setRequestAttributes(attributes);
// 执行子线程
runnable.run();
} finally {
// 线程结束,清空这些信息,否则可能造成内存泄漏
RequestContextHolder.resetRequestAttributes();
}
};
});
// 初始化线程池
executor.initialize();
log.info("初始化线程池成功");
return executor;
}
private ThreadFactory threadFactory() {
return new ThreadFactory() {
AtomicInteger threadNum = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "ThreadPoolTaskExecutor-" + threadNum.incrementAndGet());
t.start();
return t;
}
};
}
}
注意:自定义ThreadFactory创建有实际含义的线程名称,方便使用top -Hp pid和jstack pid定位到具体线程问题。