2011-09-17 28 views
37

有人可以請解釋什麼是每個請求的線程和每個連接的線程? Servlet的工作模式是什麼?如何分配線程來處理HTTP請求?它是線程/請求還是連接?如何分配線程來處理Servlet請求?

而且我們說,如果我想執行一個耗時的任務,我ServletdoGet()方法異步,我用Java執行者,這樣冗長的計算是在一個單獨的線程中完成的,併發送響應立即啓動一個新的線程。

現在是否確保我釋放了正在處理我的HttpServletRequest的線程,還是仍在使用,因爲子線程仍在運行?

回答

42

每請求裝置時的HTTP請求時,被創建或從池中檢索爲它服務的線程。一個線程服務於整個請求。每個連接的線程是相同的,除了線程用於整個連接,可能是多個請求,並且在請求之間也可能有很多空閒時間。 Servlet容器是每個請求的線程。可能有一些實現爲每個連接提供線程,但我不知道,而且看起來很浪費。

創建另一個線程中的一個線程不建立任何特殊的關係,而且在大多數情況下,這樣做的意義就在於讓一個線程做更多的工作或在其他線程繼續工作終止。在你的場景中,如你所期望的那樣,使用不同的線程來完成請求所要求的工作將允許立即發送響應。無論您的其他線程完成多長時間,用於提供該請求的線程也將立即用於其他請求。這幾乎是在每個請求線程的servlet容器中執行異步工作的方式。

注意事項:如果您使用的是完整的Java EE容器,則可能會以某種方式管理線程,這種方式會導致您自己產生一個糟糕的主意。在那種情況下,你最好向容器索要一個線程,但總的原則是一樣的。

+0

這不是你應該怎麼做異步工作在一個容器,它可能是最簡單的,但不建議。 http://stackoverflow.com/questions/533783/why-spawning-threads-in-j2ee-container-is-discouraged/533847#533847 – Robin

+0

@Robin:良好的通話。我添加了關於完整JEE容器的警告。我通常用簡單的servlet容器來思考。 –

+0

@Robin:謝謝你們。我沒有自己處理線程生命週期。我打算使用Spring的TaskExecutor abstraction.http://static.springsource.org/spring/docs/2.0.x/reference/scheduling.html#scheduling-task-executor-usage我的web應用程序工作在Tomcat 6,Spring還提供鏈接中提到的工作管理器實現,但它說它不是JEE規範。我的環境中哪一個更好? – hellojava