2009-07-27 49 views
3

由於存在雙重檢查鎖定問題,所以我們必須使用同步,以保證下面的方法(org.apache.struts.util.MessageResources類)的併發訪問:爲什麼在Struts 1.2.7中爲MessageResourcesFactory實例化?

延遲實例

public synchronized static MessageResources getMessageResources(String config) { 

    if (defaultFactory == null) { 
     defaultFactory = MessageResourcesFactory.createFactory(); 
    } 

    return defaultFactory.createResources(config); 
} 

爲什麼不使用:

EAGER實例

static { 

    // Construct a new instance of the specified factory class 
    try { 
     if (clazz == null) 
      clazz = RequestUtils.applicationClass(factoryClass); 
     MessageResourcesFactory defaultFactory = 
      (MessageResourcesFactory) clazz.newInstance(); 
    } catch (Exception e) { 
     LOG.error("MessageResourcesFactory.createFactory", e); 
    } 

} 

然後:

public static MessageResources getMessageResources(String config) { 

    return defaultFactory.createResources(config); 
} 

這將允許其至少在我的情況下,它可以被稱爲好幾次的方法getMessageResources併發訪問。

當不使用同步的意義是在這裏:

http://en.wikipedia.org/wiki/Double-checked_locking

回答

0

我認爲這是一種讓Struts確保在多線程模式下工作正常的方法,無論重寫org.apache.struts.util.MessageResources的人是否將createResources(String configuration)定義爲synchronized或不。

0

招致的同步方法在現代JVM的開銷是小得變得微不足道。隨後調用同步的lazy-init工廠方法的速度幾乎與調用非同步的eager-init方法一樣快。

就代碼而言,lazy-init方法比使用靜態初始化塊簡單易懂(在我看來)。另外,當靜態初始化塊失敗時,弄清楚在哪裏以及爲什麼會很困惑。

0

除非有什麼原因MessageResourceFactory無法在早期初始化(例如,某些Servlet資源需要首先初始化),否則我認爲我更喜歡您的解決方案。我猜想沒有任何理由讓Struts團隊懶惰地加載工廠,除此之外,這是開發人員曾經習慣的工作(即使沒有必要,人們也會懶惰地加載單身人士)。

您是否嘗試過提交錯誤報告並提出解決方案?

+0

爲什麼他們會被創建多次? – skaffman 2009-07-27 10:16:21

1

MessageResourcesFactory線程安全嗎?​​方法可以保護字段設置和createResources方法調用。如果它是線程安全的,則可以移動鎖定來覆蓋設置字段並將方法調用保留在關鍵部分之外。

相關問題