@Configuration
@EnableAsync
@Slf4j
public class ThreadPoolConfig {
@Value("${sys.thread.maxPoolSize:500}")
private int maxPoolSize;
@Bean
public ThreadPoolExecutor executorService() {
log.info("### The thread maxPoolSize is {}", maxPoolSize);
return new ThreadPoolExecutorMdcWrapper(8, maxPoolSize,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
}
/**
* 线程池MDC包装器
*/
public class ThreadPoolExecutorMdcWrapper extends ThreadPoolExecutor {
public ThreadPoolExecutorMdcWrapper(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
public ThreadPoolExecutorMdcWrapper(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
}
public ThreadPoolExecutorMdcWrapper(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
}
public ThreadPoolExecutorMdcWrapper(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
}
@Override
public void execute(Runnable command) {
super.execute(ThreadMdcUtil.wrap(command, MDC.getCopyOfContextMap()));
}
@Override
public Future<?> submit(Runnable task) {
return super.submit(ThreadMdcUtil.wrap(task, MDC.getCopyOfContextMap()));
}
@Override
public <T> Future<T> submit(Runnable task, T result) {
return super.submit(ThreadMdcUtil.wrap(task, MDC.getCopyOfContextMap()), result);
}
@Override
public <T> Future<T> submit(Callable<T> task) {
return super.submit(ThreadMdcUtil.wrap(task, MDC.getCopyOfContextMap()));
}
}
public class ThreadMdcUtil {
public static void setTraceIdIfAbsent() {
if (MDC.get(SocketConstants.TRACE_ID) != null) {
return;
}
MDC.put(SocketConstants.TRACE_ID, TraceIdUtil.getTraceId());
}
public static <T> Callable<T> wrap(final Callable<T> callable, final Map<String, String> context) {
return () -> {
if (null == context) {
MDC.clear();
} else {
MDC.setContextMap(context);
}
setTraceIdIfAbsent();
try {
return callable.call();
} finally {
MDC.clear();
}
};
}
public static Runnable wrap(final Runnable runnable, final Map<String, String> context) {
return () -> {
if (context == null) {
MDC.clear();
} else {
MDC.setContextMap(context);
}
setTraceIdIfAbsent();
try {
runnable.run();
} finally {
MDC.clear();
}
};
}
}
public class TraceIdUtil {
public static String getTraceId() {
return UUIDUtil.getUUID();
}
}
public class UUIDUtil {
public static String getUUID() {
return UUID.randomUUID().toString().replace("-", "");
}
}
@Autowired
private ThreadPoolExecutor threadPoolExecutor;
threadPoolExecutor.execute(()->{
try {
Thread.sleep(500);
} catch (InterruptedException e) {
log.error("",e);
}
});
ThreadVO threadVO = ThreadVO.builder()
//正在执行的线程
.activeCount(threadPoolExecutor.getActiveCount())
//设置的最小线程
.corePoolSize(threadPoolExecutor.getCorePoolSize())
//曾经最大的线程数
.largestPoolSize(threadPoolExecutor.getLargestPoolSize())
//设置的最大线程
.maximumPoolSize(threadPoolExecutor.getMaximumPoolSize())
//当前线程数
.poolSize(threadPoolExecutor.getPoolSize())
//已完成执行的任务的总数
.completedTaskCount(threadPoolExecutor.getCompletedTaskCount())
//线程保持活动时间
.keepAliveTime(threadPoolExecutor.getKeepAliveTime(TimeUnit.SECONDS))
//计划执行的任务总数
.taskCount(threadPoolExecutor.getTaskCount())
.build();
@Getter
@Setter(AccessLevel.PRIVATE)
@ToString
@Builder
public static class ThreadVO{
/**
* 正在执行的线程
*/
private Integer activeCount;
/**
*设置的最小线程
*/
private Integer corePoolSize;
/**
*曾经最大的线程数
*/
private Integer largestPoolSize;
/**
*设置的最大线程
*/
private Integer maximumPoolSize;
/**
*当前线程数
*/
private Integer poolSize;
/**
*已完成执行的任务的总数
*/
private Long completedTaskCount;
/**
*线程保持活动时间
*/
private Long keepAliveTime;
/**
*计划执行的任务总数
*/
private Long taskCount;
}