2011-01-26 33 views
3

我遇到了一種情況:我使用ThreadLocal靜態變量在請求的生命週期中容納包含來自不同類的各種度量值的bean。在一個過濾器中,我創建了這個bean,並將其設置在一個線程局部變量中,並在請求處理後從同一個過濾器中的線程局部變量中移除它。我碰到的是包含來自其他請求的值的bean!對此的唯一解釋是共享的線程同時處理多個請求。所以標題中的問題。是否爲servlet處理的整個請求保證線程?

回答

6

雖然一個線程一般將處理單個請求(談到的Tomcat,肯定的),該線程可處理隨着時間的推移多個請求而不是W/O完成現有請求,除非使用包括/向前相似者。

我非常strognly建議您使用屬性瓦特/你的bean上述要求(的setAttribute()),並用它來分析。如果你不能提供各種方法的請求......那麼你被困在ThreadLocal [這不是太糟糕的解決方案]。

或者,您可以發佈代碼如何安裝/刪除threadLocal bean。

請記住,你必須向一些管理這個bean,以及(這將無法使用要求外)。

編輯:忘了問:你使用try/finally調用doFilter(...)?

的代碼應該是這樣的

installBean(); 
try{ 
    chain.doFilter(req, resp); 
}finally{ 
Bean b = deinstallBean(); 
useTheMetrics(b); 
//potentially, process exception, etc 
} 
+0

是的,「終於」做到了神奇。就像邁克爾和埃裏克森所說的那樣,在一種情況下,運行時異常並沒有移除bean。謝謝。 – Murali 2011-01-26 23:39:36

+0

拇指規則(或故事的道德):如果您修改任何全局狀態並打算將其撤回。使用try/finally,實際上使用try/finally需要任何清理/關閉/處理(或隱式回滾),它幾乎不會導致任何性能損失(認爲它是免費的:D) – bestsss 2011-01-26 23:45:32

2

也可能是您的過濾器並不總是以您期望的順序調用。線程被重用來一個接一個地處理多個請求,所以如果ThreadLocal中的值沒有被移除,那麼當線程處理它的下一個請求時它仍然會在那裏。

1

是的,你可以假設一個單獨的線程將處理每個請求。

使用finally塊在處理鏈的其餘部分後清除(設置爲null)過濾器中的ThreadLocal。這將防止以前請求中的數據與當前請求混雜在一起。

相關問題