2014-10-22 32 views
0

我已經配置兩個類SomeService和依賴和有線經由彈簧:是否有可能重現可見性錯誤?

@Named 
public class SomeService implements Service 
{ 

    @Inject 
    public Dependency dependency; 

    public void execute() 
    { 
     dependency.execute(); 
    } 
} 



@Named 
public class Dependency 
{ 
    public void execute() 
    { 

    } 
} 

在一些少見的情況下SomeService.execute()拋出NPE。我想這個問題是非最終/非易失性字段不能從不同的線程訪問沒有外部同步。相當明顯的解決方法是使Dependency字段最終並用構造函數注入替換字段注入。但是我試圖在本地機器上使用一個啓動ApplicationContext的線程和幾個其他嘗試獲取SomeService的線程來重現最初的錯誤。在所有情況下,依賴關係從未爲空。是否有可能使測試案例再現問題? 預先感謝您。

+0

首先,您可以將'dependency'作爲'private'字段。我的猜測是,無論是將它設置爲「null」,還是在別的地方都不使用依賴關係('New SomeService')的情況下創建一個'Service'實例。使字段'private'並創建一個非默認的構造函數(不要創建無參數的構造函數)並檢查不再編譯的內容。 – SJuan76 2014-10-22 12:19:37

+0

這只是真實課程的一個簡短例子。在真實的類中字段是私有的,SomeService類使用org.springframework.beans.factory.BeanFactory#getBean(java.lang.Class )實例化。 – 2014-10-22 12:28:44

+0

您也可以使用構造函數注入來使它們最終。 – rlegendi 2014-10-22 13:40:37

回答

0

像這樣的併發錯誤有時很難在單插槽硬件上重現,因爲由於共享(L3)高速緩存,內核位置處的內核中的不同值的時間很短。在多路服務器硬件上,由於跨節點同步內存的時間更長,因此可能會更容易些。這也限制了大型機器的可擴展性。如果你在小型機器上進行開發和測試,但是在大鐵上運行,這會讓你受到很大影響。

無論如何,這是一個經典的併發陷阱,可以通過使用final輕鬆避免,正如您和其他人所提及的。

因此,您可能會在多插槽硬件上看到它更容易/更經常,但當然不能保證。

+0

好吧,謝謝大家,我只是想知道是否有任何好方法來重現此類問題。 – 2014-10-23 08:25:54

相關問題