两种实现方式:
定义任务装饰器
package com.dc.smart.core.config.mdc;
import org.slf4j.MDC;
import org.springframework.core.task.TaskDecorator;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author coco
* @date 2022/11/15
*/
@Component
public class MdcTaskDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
// Right now: Web thread context !
// (Grab the current thread MDC data)
Map contextMap = MDC.getCopyOfContextMap();
return () -> {
try {
// Right now: @Async thread context !
// (Restore the Web thread context's MDC data)
if (contextMap != null) {
MDC.setContextMap(contextMap);
}
runnable.run();
} finally {
MDC.clear();
}
};
}
}
配置线程池
package com.dc.smart.core.config.mdc;
import com.dc.smart.core.config.mdc.MdcTaskDecorator;
import com.dc.smart.core.config.mdc.MdcThreadPoolTaskExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author coco
* @date 2022/11/15
*/
@Configuration
public class ThreadPoolConfig{
//参数初始化
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
//核心线程数量大小
private static final int corePoolSize = Math.max(2, Math.min(CPU_COUNT - 1, 4));
//线程池最大容纳线程数
private static final int maxPoolSize = CPU_COUNT * 2 + 1;
//阻塞队列
private static final int workQueue = 20;
//线程空闲后的存活时长
private static final int keepAliveTime = 30;
@Autowired
private MdcTaskDecorator mdcTaskDecorator;
@Bean("ndAsyncTaskExecutor")
public ThreadPoolTaskExecutor getAsyncExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
//核心线程数
threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
//最大线程数
threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
//等待队列
threadPoolTaskExecutor.setQueueCapacity(workQueue);
//线程前缀
threadPoolTaskExecutor.setThreadNamePrefix("ndAsyncTask-");
//线程池维护线程所允许的空闲时间,单位为秒
threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveTime);
// 线程池对拒绝任务(无线程可用)的处理策略
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
threadPoolTaskExecutor.setTaskDecorator(mdcTaskDecorator);
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}
package com.dc.smart.core.config.mdc;
import lombok.NonNull;
import org.slf4j.MDC;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* @author coco
* @date 2022/11/15
*/
public class MdcThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
final private boolean useFixedContext;
final private Map fixedContext;
/**
* Pool where task threads take MDC from the submitting thread.
*/
public static MdcThreadPoolTaskExecutor newWithInheritedMdc(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, int queueCapacity) {
return new MdcThreadPoolTaskExecutor(null, corePoolSize, maximumPoolSize, keepAliveTime, unit, queueCapacity);
}
private MdcThreadPoolTaskExecutor(Map fixedContext, int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit, int queueCapacity) {
setCorePoolSize(corePoolSize);
setMaxPoolSize(maximumPoolSize);
setKeepAliveSeconds((int) unit.toSeconds(keepAliveTime));
setQueueCapacity(queueCapacity);
this.fixedContext = fixedContext;
useFixedContext = (fixedContext != null);
}
private Map getContextForTask() {
return useFixedContext ? fixedContext : MDC.getCopyOfContextMap();
}
/**
* All executions will have MDC injected. {@code ThreadPoolExecutor}'s submission methods ({@code submit()} etc.)
* all delegate to this.
*/
@Override
public void execute(@NonNull Runnable command) {
super.execute(wrap(command, getContextForTask()));
}
@NonNull
@Override
public Future> submit(@NonNull Runnable task) {
return super.submit(wrap(task, getContextForTask()));
}
@NonNull
@Override
public Future submit(@NonNull Callable task) {
return super.submit(wrap(task, getContextForTask()));
}
private static Callable wrap(final Callable task, final Map context) {
return () -> {
Map previous = MDC.getCopyOfContextMap();
if (context == null) {
MDC.clear();
} else {
MDC.setContextMap(context);
}
try {
return task.call();
} finally {
if (previous == null) {
MDC.clear();
} else {
MDC.setContextMap(previous);
}
}
};
}
private static Runnable wrap(final Runnable runnable, final Map context) {
return () -> {
Map previous = MDC.getCopyOfContextMap();
if (context == null) {
MDC.clear();
} else {
MDC.setContextMap(context);
}
try {
runnable.run();
} finally {
if (previous == null) {
MDC.clear();
} else {
MDC.setContextMap(previous);
}
}
};
}
}
package com.dc.smart.core.config.mdc;
import com.dc.smart.core.config.mdc.MdcTaskDecorator;
import com.dc.smart.core.config.mdc.MdcThreadPoolTaskExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author coco
* @date 2022/11/15
*/
@Configuration
public class ThreadPoolConfig{
//参数初始化
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
//核心线程数量大小
private static final int corePoolSize = Math.max(2, Math.min(CPU_COUNT - 1, 4));
//线程池最大容纳线程数
private static final int maxPoolSize = CPU_COUNT * 2 + 1;
//阻塞队列
private static final int workQueue = 20;
//线程空闲后的存活时长
private static final int keepAliveTime = 30;
@Autowired
private MdcTaskDecorator mdcTaskDecorator;
@Bean("ndAsyncTaskExecutor")
public ThreadPoolTaskExecutor getAsyncExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = MdcThreadPoolTaskExecutor.newWithInheritedMdc(corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue);
//核心线程数
threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
//最大线程数
threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
//等待队列
threadPoolTaskExecutor.setQueueCapacity(workQueue);
//线程前缀
threadPoolTaskExecutor.setThreadNamePrefix("ndAsyncTask-");
//线程池维护线程所允许的空闲时间,单位为秒
threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveTime);
// 线程池对拒绝任务(无线程可用)的处理策略
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
threadPoolTaskExecutor.setTaskDecorator(mdcTaskDecorator);
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}