import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 异步线程池配置类
*/
@Configuration
@EnableAsync
@Slf4j
public class SmsConfiguration {
@Value("${async-sms.core-pool-size:4}")
private Integer corePoolSize;
@Value("${async-sms.max-pool-size:16}")
private Integer maxPoolSize;
@Value("${async-sms.queue-capacity:100}")
private Integer queueCapacity;
@Value("${async-sms.thread-name-prefix:async-sms-}")
private String threadNamePrefix;
@Bean
public MDCThreadPoolExecutor getMDCThreadPoolExecutor(){
return new MDCThreadPoolExecutor();
}
@Bean
public Executor asyncSmsServiceExecutor(MDCThreadPoolExecutor executor) {
log.info("start asyncSmsServiceExecutor");
//配置核心线程数
executor.setCorePoolSize(corePoolSize);
//配置最大线程数
executor.setMaxPoolSize(maxPoolSize);
//配置队列大小
executor.setQueueCapacity(queueCapacity);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix(threadNamePrefix);
// RequestContextHolder 解决子线程NP问题
executor.setTaskDecorator(new ContextDecorator());
// 设置拒绝策略:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.concurrent.ListenableFuture;
public class MDCThreadPoolExecutor extends ThreadPoolTaskExecutor {
public MDCThreadPoolExecutor() {
}
public Future<?> submit(Runnable task) {
return super.submit(ThreadMDCUtils.setTraceIdFromParent(task));
}
public <T> Future<T> submit(Callable<T> task) {
return super.submit(ThreadMDCUtils.setTraceIdFromParent(task));
}
public ListenableFuture<?> submitListenable(Runnable task) {
return super.submitListenable(ThreadMDCUtils.setTraceIdFromParent(task));
}
public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
return super.submitListenable(ThreadMDCUtils.setTraceIdFromParent(task));
}
public void execute(Runnable task) {
super.execute(ThreadMDCUtils.setTraceIdFromParent(task));
}
public void execute(Runnable task, long startTimeout) {
super.execute(ThreadMDCUtils.setTraceIdFromParent(task), startTimeout);
}
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import org.slf4j.MDC;
public class ThreadMDCUtils {
public ThreadMDCUtils() {
}
public static Runnable setNewTraceId(final Runnable runnable) {
return new Runnable() {
public void run() {
ThreadMDCUtils.setTraceId();
try {
runnable.run();
} finally {
MDC.clear();
}
}
};
}
public static <T> Callable<T> setNewTraceId(final Callable<T> callable) {
return new Callable<T>() {
public T call() throws Exception {
ThreadMDCUtils.setTraceId();
Object var1;
try {
var1 = callable.call();
} finally {
MDC.clear();
}
return var1;
}
};
}
public static Runnable setTraceIdFromParent(final Runnable runnable) {
final Map<String, String> threadContext = MDC.getCopyOfContextMap();
return new Runnable() {
public void run() {
if (threadContext == null) {
MDC.clear();
} else {
MDC.setContextMap(threadContext);
}
ThreadMDCUtils.setTraceIdIfAbsent();
try {
runnable.run();
} finally {
MDC.clear();
}
}
};
}
public static <T> Callable<T> setTraceIdFromParent(final Callable<T> callable) {
final Map<String, String> threadContext = MDC.getCopyOfContextMap();
return new Callable<T>() {
public T call() throws Exception {
if (threadContext == null) {
MDC.clear();
} else {
MDC.setContextMap(threadContext);
}
ThreadMDCUtils.setTraceIdIfAbsent();
Object var1;
try {
var1 = callable.call();
} finally {
MDC.clear();
}
return var1;
}
};
}
public static void setTraceId() {
MDC.put("Request-Id", getRandomTraceId());
}
public static String getTraceId() {
return MDC.get("Request-Id");
}
public static void setTraceIdIfAbsent() {
if (MDC.get("Request-Id") == null) {
MDC.put("Request-Id", getRandomTraceId());
}
}
public static String getRandomTraceId() {
return UUID.randomUUID().toString().replace("-", "");
}
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import org.springframework.core.task.TaskDecorator;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
public class ContextDecorator implements TaskDecorator {
public ContextDecorator() {
}
public Runnable decorate(Runnable runnable) {
RequestAttributes context = null;
try {
context = RequestContextHolder.currentRequestAttributes();
} catch (IllegalStateException var4) {
}
RequestAttributes finalContext = context;
return () -> {
try {
RequestContextHolder.setRequestAttributes(finalContext);
runnable.run();
} finally {
RequestContextHolder.resetRequestAttributes();
}
};
}
}
线程池配置类
于 2025-04-23 15:47:19 首次发布