2013-05-12 22 views
0

我有一個servlet,我想爲Web UI提供數據。 數據存儲在一個xml文件中,我希望這個文件可以在幾天內修改一次。 我想在servlet中加載xml文件一次,併爲每個請求提供服務,並只在發送另一個「重新加載」請求時才重新加載它。如何將靜態數據存儲在servlet中並在所有會話/請求之間共享?

從我讀到的,servlet中的靜態變量是不好的做法。

我該如何實現我所需要的?

謝謝。

回答

2

servlet在webapp的啓動時只創建一次,並在所有請求之間共享。靜態與否,每個類/實例變量將在所有請求/會話中共享。你不想爲它們分配請求/會話範圍的數據。相反聲明/將它們分配爲methodlocal變量

SEE HERE

+0

但是,如何使靜態的一個線程安全嗎? – user1997656 2013-05-12 10:57:36

0

只需創建一個靜態變量,你不必做任何事情,更

1

可以使用Singleton模式或CDI應用範圍的Bean取決於您的環境。

不要忘記線程安全。

public class ServletSingleton { 
    private static ServletSingleton instance = new ServletSingleton(); 

    //Here is your data objects 
    private Object firstDataObject; 
    private Object secondDataObject; 

    public static Object getFirstDataObject(){ 
     synchronized (instance){ 
      return instance.firstDataObject; 
     } 
    } 

    public static Object getSecondDataObject(){ 
     synchronized (instance){ 
      return instance.secondDataObject; 
     } 
    } 

    public static void setFirstDataObject(Object dataObject){ 
     synchronized (instance){ 
      instance.firstDataObject = dataObject; 
     } 
    } 

    public static void setSecondDataObject(Object dataObject){ 
     synchronized (instance){ 
      instance.secondDataObject = dataObject; 
     } 
    } 
} 

這是不熟悉的單身人士,但它使用相同的原則。

+0

你能指點我一個例子嗎? – user1997656 2013-05-12 10:56:59

+0

是的,當然。我編輯了我的答案,所以現在它包含線程安全準單例的示例。 – gluckonavt 2013-05-12 11:41:58

0

您可以定義一個實例成員或存儲屬性到應用範圍,但兩者都不是線程安全的。

3

我真的不喜歡「壞習慣」這個詞,因爲它暗示我們可以評估是否有什麼不好的情況。如果Java語言的設計者認爲靜態字段總是不好的話,那麼這種情況很少會發生 - 或者換言之,他們不會將它們包含在語言中。

在servlet中有可變狀態是完全可以的 - 但是你必須記住,servlet容器將使用servlet的同一對象實例來(併發地)爲所有請求提供服務。

這意味着特定於請求的狀態不應該存儲在servlet中,因爲不同的請求處理線程會覆蓋彼此的狀態。在你的情況下,你希望狀態在所有請求之間共享,所以servlet中的字段是合適的。由於servlet是由併發線程訪問的,您將不得不同步訪問該可變共享狀態。

+0

如何同步訪問servlet中的數據?只是用同步包裝的方法? – user1997656 2013-05-12 11:15:43

+0

如何編寫正確的線程安全代碼超出了本答案的範圍。 java教程對該主題有一個[介紹](http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html)。 – meriton 2013-05-12 11:22:33

相關問題