2010-08-02 92 views
1

在Tomcat容器中,執行與servlet相關的所有過濾器,並且servlet本身使用相同的線程?即將doFilter()與servlet的service()方法在同一個線程中運行?提前致謝。Tomcat中的Servlet,過濾器和線程

回答

-1

是的,每個請求都在一個servlet實例中執行.Servlet容器接收每個請求並啓動一個包含HttpServletRequest和HttpServletResponse的新線程。該線程處理servlet實例的service方法中的請求,並在服務方法完成後立即銷燬。

+0

servlet容器管理servlet生命週期,而不是開發人員。 – duffymo 2010-08-02 09:27:57

+1

服務方法是不同步的 - 除非servlet實現SingleThreadModel接口,Tomcat會很高興地運行線程並行服務相同的servlet。 – nos 2010-08-02 09:35:58

+0

請注意,自5年前Servlet 2.4以來,'SingleThreadModel'已被**棄用**。你不應該使用它。這將表明一個*糟糕的設計*。 – BalusC 2010-08-02 11:14:34

4

是的,每個請求都在單個線程中執行,包括所有過濾器和目標servlet。

3

我懷疑問題更多:我可以使用ThreadLocal對象在過濾器和servlet之間傳遞數據嗎?在這種情況下,答案是絕對的。應用服務器自己做這件事來跟蹤安全,交易,連接和其他請求信息。

只要確保在設置ThreadLocal的相同代碼中的finally塊中清除了ThreadLocal。正如其他人已經指出的那樣,servlet本身可能是也可能不是同步的,但它與線程狀態的概念是正交的;即針對對象foo執行多少個線程與我可以在線程中放入狀態並讓它通過對象foo看到。第二個問題的答案總是肯定的。

答案是「不」,就是如果你利用任何異步通信的唯一時間:

  • 通過AsyncContext調度呼叫
  • 在EJB中混合,並開始利用@Asynchronous或中TimerService

這些涉及應用程序服務器啓動與原始請求線程無關的新線程,所以任何ThreadLocal狀態都不會與新線程一起移動。這也是爲什麼這些API不允許將調用者的安全和事務上下文傳播到調用的方法,因爲調用者和方法在不同的線程中。

高級注意事項,InheritableThreadLocal通常不起作用,因爲異步調用通常由服務器針對線程池完成,而不是創建調用者線程的子線程。