slf4j初始化线程安全历险记

最近发现项目中的日志用得不大规范,于是准备做些改造,在我们项目中用的是 slf4j1.5.10 的版本,顺便看了下 slf4j 的源码,看到 LoggerFactory 初始化的逻辑如下

  public static ILoggerFactory getILoggerFactory() {
    if (INITIALIZATION_STATE == UNINITIALIZED) {
      INITIALIZATION_STATE = ONGOING_INITILIZATION;
      performInitialization();
    }
    switch (INITIALIZATION_STATE) {
    case SUCCESSFUL_INITILIZATION:
      return getSingleton().getLoggerFactory();
    case FAILED_INITILIZATION:
      throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
    case ONGOING_INITILIZATION:
      // support re-entrant behavior.
      // See also http://bugzilla.slf4j.org/show_bug.cgi?id=106
      return TEMP_FACTORY;
    }
    throw new IllegalStateException("Unreachable code");
  }

有发现什么问题吗?再看看 INITIALIZATION_STATE 这个变量是怎么声明的,如下

  static int INITIALIZATION_STATE = UNINITIALIZED;

现在很明确了,如果在多线程环境下,多个线程调用 LoggerFactory.getLogger() 方法的时候初始化会出现问题,这简直有点颠覆世界观,说好的大神代码呢?怀着极度怀疑自己的心情翻看了最新的 slf4j1.7.21 代码,看到初始化逻辑如下:

     public static ILoggerFactory getILoggerFactory() {
        if (INITIALIZATION_STATE == UNINITIALIZED) {
            synchronized (LoggerFactory.class) {
                if (INITIALIZATION_STATE == UNINITIALIZED) {
                    INITIALIZATION_STATE = ONGOING_INITIALIZATION;
                    performInitialization();
                }
            }
        }
        switch (INITIALIZATION_STATE) {
        case SUCCESSFUL_INITIALIZATION:
            return StaticLoggerBinder.getSingleton().getLoggerFactory();
        case NOP_FALLBACK_INITIALIZATION:
            return NOP_FALLBACK_FACTORY;
        case FAILED_INITIALIZATION:
            throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
        case ONGOING_INITIALIZATION:
            // support re-entrant behavior.
            // See also http://jira.qos.ch/browse/SLF4J-97
            return SUBST_FACTORY;
        }
        throw new IllegalStateException("Unreachable code");
    }

再看看 INITIALIZATION_STATE 变量的声明

        static volatile int INITIALIZATION_STATE = UNINITIALIZED;

顿时泪流满面,这才像传说中的大神代码啊

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,303评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 177,370评论 25 709
  • 你的好,别人代替不了。 许多当下的迷茫,只是烦乱的心情需要一场宣泄,其实自己心里,早已定了主意。 有时候你戏称灌给...
    乔文景阅读 215评论 2 1
  • 夜晚,有很多声音。 下雨的时候有雨滴声,在房檐上敲打,落下,混乱的砸在地上,溅起另一片声响。闷热的...
    肖草生阅读 360评论 0 1
  • 算起来,现在的我已经不是一个游戏的时髦派了。当年PSVita首发时我立即入手了一台,游戏机的硬件指标倒是给我惊艳不...
    东漂的云阅读 19,019评论 0 0

友情链接更多精彩内容