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;

頓時淚流滿面,這才像傳說中的大神代碼啊

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,837評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,846評論 25 708
  • 你的好,別人代替不了。 許多當下的迷茫,只是煩亂的心情需要一場宣泄,其實自己心里,早已定了主意。 有時候你戲稱灌給...
    喬文景閱讀 207評論 2 1
  • 夜晚,有很多聲音。 下雨的時候有雨滴聲,在房檐上敲打,落下,混亂的砸在地上,濺起另一片聲響。悶熱的...
    肖草生閱讀 282評論 0 1
  • 算起來,現在的我已經不是一個游戲的時髦派了。當年PSVita首發時我立即入手了一臺,游戲機的硬件指標倒是給我驚艷不...
    東漂的云閱讀 18,321評論 0 0