2014-07-11 189 views
1

我需要通過servlet調用提供一些文本。該文本是從多個複雜的數據庫讀取中獲得的,因此我創建了一個文件來存儲「呈現」文本作爲緩存的手段。如果文件存在並且緩存不舊,用戶將被重定向到該文件,這需要很少的時間。否則,文件被重新創建,用戶也被重定向到文件。這個servlet是線程安全的嗎?

有經驗的程序員會注意到這有明顯的競爭條件。第一個解決方案嘗試同步創建文件的塊。但是,這仍然有一個競爭條件。

第二個解決方案同步整個方法,而不是重定向到文件,它打印出方法內的文本。

protected synchronized void processRequest(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 

// if file doesnt exist, create file 
// if cache is old, recreate file 
// printout file 
} 

我的問題是:

  1. 這是線程安全的?我的意思是,servlet在解鎖對象之前是否將所有數據發送到客戶端?或者對象被解鎖,然後servlet開始將結果發送給客戶端?
  2. 表現受到嚴重影響。有沒有其他的方式來提高性能,同時保持線程安全?

編輯

只是爲了澄清,該servlet通過到另一個類的靜態方法的調用來創建該文件:Cache.createFile()。這個方法只能被servlet訪問。如果不是不可能的話,該文件與任何其他外部應用程序的碰撞是極不可能的。 createFile()總是寫入相同的文件。

回答

-1

該servlet是線程安全的..但是對於每個請求都有一個新的線程分配給servlet類,在這種情況下,您有多個線程運行多個servlet實例。現在取決於你如何在你的方法中編寫(代碼),這可能導致你處於競爭狀態。

但是你用創建邏輯創建了一些類似於對象的單例。

+0

嗯......嗯,其實如果有運行多個線程,只有一個被允許在同一時間運行的方法,所以我視看不到比賽狀態如何方法被編碼。 – user1156544

+1

決定你的想法。要麼它是線程安全的或有競爭條件。你的回答沒有意義。 – EJP

-1

正如Jigar joshi已經給出了你的問題的答案。所以你可以在這裏實現單例模式來提高性能。在你的案例文件是一個資源,所以你必須同步它不完整的方法。我們的代碼SHD樣子

protected void processRequest(HttpServletRequest request, HttpServletResponse response) 
       throws ServletException, IOException { 

    if file doesnt exist OR cache is old 
     synchronized(this){ // if instance method 
      if file doesnt exist OR cache is old // chk again to avoid re-generation of file 
       create file 
     } 
    } 

    read file data OR printout file 
} 
+0

對不起,但您的代碼已損壞(另請參閱雙重條件)並且因多種原因無法正常工作 – user1156544

+0

查看代碼中的註釋 –

+0

是的,我已經看到它們。但在很多情況下它失敗了。一種是當你打印文件時,其他任何人都可以進入同步塊並在同一時間修改文件。雙重檢查是不安全的 - 你不能「揮發」文件。 – user1156544