m0_62946064 2022-08-15 15:48 采纳率: 100%
浏览 114
已结题

(Java)volatile关键字失效?!亲测失效!重现代码已放至GitHub

各位大仙,这不科学!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,一直是。

why?

  • 写回答

2条回答 默认 最新

  • 於黾 2022-08-15 15:58
    关注

    go函数执行了吗
    go里没有循环,3秒就直接退出了?

    本回答被专家选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 11月16日
  • 专家已采纳回答 11月8日
  • 修改了问题 8月15日
  • 修改了问题 8月15日
  • 展开全部

悬赏问题

  • ¥15 伪标签为什么不能作为弱监督语义分割的结果?
  • ¥15 编一个判断一个区间范围内的数字的个位数的立方和是否等于其本身的程序在输入第1组数据后卡住了(语言-c语言)
  • ¥15 游戏盾如何溯源服务器真实ip?
  • ¥15 Mac版Fiddler Everywhere4.0.1提示强制更新
  • ¥15 android 集成sentry上报时报错。
  • ¥50 win10链接MySQL
  • ¥15 抖音看过的视频,缓存在哪个文件
  • ¥15 自定义损失函数报输入参数的数目不足
  • ¥15 如果我想学习C大家有是的的资料吗
  • ¥15 根据文件名称对文件进行排序