2017-09-04 55 views
0

安全我用它這種設計模式在J2EE:保證線程在J2EE

public class myClass{ 
    private static Hashtable<Integer, ContentClass> contents = new Hashtable<Integer, ContentClass>(); 
public synchronized static void m1(){ 
//some work on contents 

} 
public synchronized static void m2(){ 
//another some work on contents 

} 

我想在運行glassfish 3服務器部署此。

測驗1:它是保證線程安全嗎?

測驗2:如果類更改爲有狀態EJB發生了什麼?它是線程安全的嗎?

+2

不僅它是*不是線程安全的,而且每個服務器的Hashtable內容也會不同。不僅每臺服務器作爲一臺物理/虛擬機,而且每臺JVM - 這意味着即使應用程序運行在同一臺「機器」上但在不同的服務器實例上運行,也不會有(a)沒有線程安全保證和(b)內容'會有所不同。您可能需要查看分佈式緩存解決方案(例如Ehcache,Hazelcast,Infinispan)。 –

+0

@NikosParaskevopoulos謝謝。如果你認爲這個程序只運行在一個jvm上會發生什麼情況?分佈式緩存解決方案不會自動放入glassfish中? – DanialAbdi

回答

1

如果要在運行glashfish的三臺服務器之間共享一個bean,則需要使用EJB持久性和實體bean,而不是使用無狀態或有狀態會話bean。但是,EJB持久性不適用於靜態成員。

因此,你應該寫:

public class myClass{ 
    private Hashtable<Integer, ContentClass> contents = new Hashtable<Integer, ContentClass>(); 
    public synchronized void m1(){ 
//some work on contents 

} 
public synchronized void m2(){ 
    //another some work on contents 
} 

,並添加註釋或其他方式來解釋容器如何堅持contents有某種映射。

這樣,您可以將此實體Bean持久保存到共享數據源,並且這三個服務器將能夠正確訪問它。所以,你需要定義一個數據源,一個持久化單元和一個實體管理器來管理這個bean的實例。

這樣,你的代碼將是線程安全的。訪問contents將正確完成。

+0

非常感謝。你的回答對我很有用,並向我展示新的方法。 – DanialAbdi

相關問題