各位大仙,这不科学!ThreadPoolTaskExecutor+logback的TurboFilter,在其他线程修改了volatile关键字修饰的静态变量的值,在线程池中其他线程里的turbofilter代码中读取该静态变量的值却一直读不到最新值,不是延迟读不到,是一直读不到!给我整不会了,重现代码在https://github.com/qinhaiqinshui/volatileTest
情况是这样的
使用spring boot 定时运行分析任务,在线程池中运行分析任务,想每次分析日志记录在一个日志文件中,但又不想每次调logger.info之前都调一次MDC.put("分析id",id),于是通过写logback的TurboFilter,在filter里面调MDC.put,但是在filter中却一直获取不到每次任务开始时最新生成的分析id。
关键代码
保存运行日志代码
public class AnalysisLog {
private static volatile AnalysisLog currentAnalysis;
public static AnalysisLog getCurrentAnalysis() {
return currentAnalysis;
}
public static void setCurrentAnalysis(AnalysisLog currentAnalysis) {
currentAnalysis = currentAnalysis;
}
private Long id;
private Integer status;
}
任务开始时设置新的分析日志对象
@Service
public class LogService {
private Logger logger= LoggerFactory.getLogger(this.getClass());
private MyLogger myLogger=new MyLogger();
@Async
public void go(){
AnalysisLog analysisLog=new AnalysisLog();
analysisLog.setId(111L);
AnalysisLog.setCurrentAnalysis(analysisLog);
logger.info("开始记录");
myLogger.info("mylog开始:");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
logger.info("完成");
myLogger.info("mylog完成:");
}
}
在filter中读取
public class MDCTurboFilter extends TurboFilter {
@Override
public FilterReply decide(Marker marker, Logger logger, Level level, String s, Object[] objects, Throwable throwable) {
if (logger.getName().startsWith("com.example.demo.service")){
System.out.println("CurrentAnalysis:"+AnalysisLog.getCurrentAnalysis());
}
return FilterReply.NEUTRAL;
}
}
运行结果
CurrentAnalysis 一直是null,一直是。