2008-11-26 66 views
6

對於擁有變量的servlet所做的所有請求,threadlocals變量是否全局?servlet中的threadlocal變量

我使用樹脂作爲服務器。

感謝您的支持者。

我想我可以讓自己更清楚。

具體情況:

我想:

  • 初始化靜態變量當請求開始執行。
  • 能夠查詢在從一個線程安全的方式在servlet調用的方法的進一步執行變量的值,直到請求結束執行

回答

3

我認爲他們是全球對與發出的所有請求只有特定的線程。其他線程獲取線程本地數據的其他副本。這是線程本地存儲的關鍵點: http://en.wikipedia.org/wiki/Thread-local_storage#Java

除非您檢查servlets配置中的相應選項,否則servlet容器將使用您的servlet和多個線程來並行處理請求。因此,有效地,您將爲服務客戶端的每個線程分別分配數據。

如果您的WebApplication未分佈(可在多個Java虛擬機上運行),則可以使用ServletContext對象跨請求和線程存儲共享數據(請確保正確鎖定)。

+0

確實。在以前的項目中,我在會話中存儲了用戶票據,並創建了一個過濾器,將票證從會話轉移到本地線程,以確保用戶的身份驗證狀態始終對處理請求的線程可用。 – Julie 2008-11-26 19:47:25

0

Threadlocal變量總是被定義爲全局訪問,因爲重點是透明地將信息傳遞到可以在任何地方訪問的系統。變量的值綁定到它所在的線程,因此即使該變量是全局變量,它也可以具有不同的值,具體取決於訪問它的線程。

一個簡單的例子是,當servlet中接收到請求時,將一個用戶標識字符串分配給線程局部變量中的一個線程。在該請求的處理鏈中的任何位置(假設它位於同一個VM中的同一線程上),可以通過訪問此全局變量來檢索身份。在處理請求時刪除此值也很重要,因爲該線程將放回到線程池中。

2

就像Adiel說的,正確的做法是使用請求上下文(即HttpServletRequest),而不是創建一個ThreadLocal。雖然在這裏可以使用ThreadLocal,但是如果你這樣做的話,你必須小心地清理你的線程,因爲否則下一個獲取線程的請求將會看到與前一個請求相關聯的值。 (當線程完成第一個請求時,線程將返回到池中,因此下一個請求將會看到它。)沒有理由必須在請求上下文存在時正好處理這種事情。

+0

你也可以使用servlet過濾器來管理ThreadLocal,至少創建/清理應該在一個地方。 – sehugg 2009-06-11 17:09:41

+1

-1「管理這種事情」確實有很好的理由,與僅有一個靜態獲取者相比,在應用程序周圍傳遞1000次參數存在差異;-) – peenut 2013-02-22 06:58:55

4

簡答:是的。
稍長一點:這就是Spring如何發揮它的魔力。請參閱RequestContextHolder(通過DocJar)。

雖然需要小心 - 您必須知道何時使ThreadLocal無效,如何推遲到其他線程,以及如何與非線程本地上下文糾結。

或者你可以只使用Spring ...

1

使用ThreadLocal的存儲請求範圍信息已經打破,如果你使用的Servlet 3.0懸浮請求(或Jetty延續) 使用這些API的多線程處理一個潛在的請求。