2010-08-04 116 views
18

我對web開發相當陌生。所以我很抱歉如果這是一個非常基本的問題。例如,我創建一個Web應用程序並將其部署到tomcat。現在,當多個用戶點擊Web應用程序時,tomcat是否爲每個用戶創建一個新線程?如果是這樣的話,我還可以在我的應用程序本身中創建線程,並希望它保持本地到tomcat創建的每個用戶線程?會話級數據是否在線程間保持同步?tomcat是否爲每個用戶創建一個線程?

我希望我的問題有道理。

+2

你可能會發現[這個答案](http://stackoverflow.com/questions/3106452/java-servlet-instantiation-and-session-variables/3106909#3106909)也很有幫助。 – BalusC 2010-08-04 01:51:56

回答

35

每個請求在不同的線程中處理。這不是「每個用戶的線程」。請求是來自客戶端(網絡瀏覽器)和服務器的任何交互。因此,在瀏覽器中輸入一個Url,調用一個Ajax請求,每個請求都在一個單獨的線程中處理。

用戶在「登錄」期間獲取的狀態(它本身不一定是登錄;更好的方式來說它是「一個用戶的一組相關請求」)方便地存儲在會話。您可以使用會話來存儲適用於用戶的任何數據,但應注意不要存儲太多的數據,因爲它會消耗內存。會話管理需要一定的技巧。

是的,你必須非常小心,如果你發射新線程;你可以破壞事物,通常是一個壞主意。如果你必須做一些需要很長時間的事情,那麼使用JMS來處理異步的任何事情。另外請記住,並非所有影響Web應用程序數據的任務都必須從webapp調用。每天掃描數據的任務可以作爲一個單獨的任務在tomcat中運行或不運行 - 也就是說,您可以使用諸如quartz調度程序之類的東西編寫任務,甚至編寫單獨的程序並將其設置爲在cron中運行(是儘管如此,小心改變webapp下的數據)。

如果您正在使用Spring和Hibernate等最佳技術,它們通常會綁定對象(或可由應用程序開發人員配置),程序員將需要爲每個線程(使用java的ThreadLocal)。

這也是開始你自己的線程是危險的原因之一。如果您啓動自己的線程,那麼在請求結束時,可能會丟失綁定到初始線程的資源,這意味着如果嘗試訪問工作線程中的這些資源,則無法使用它們。這種類型的錯誤可能是尋找/修復屁股的痛處。

編輯 - 正如Stephen C在另一個答案的評論中指出的那樣,重要的是要注意,通常Tomcat(和其他容器)維護一個線程池供使用。這意味着不一定爲每個請求創建一個新線程。這意味着每個請求在單獨的線程中運行,該線程可能會或可能不會被創建或重用。

+1

感謝您的詳細解答。某人在Web應用程序中如何執行併發任務?即使你可以從中獲得表現,它通常是可以避免的嗎? – user377067 2010-08-04 02:03:19

+2

你是什麼意思的併發?如果請求啓動需要很長時間的任務,則需要異步處理。使用JMS是這裏的答案。這個想法是你發送一個消息到一個隊列或主題(並且發起請求結束),並且一個bean(消息驅動的bean)被配置爲觀察隊列或者主題並且消費它上面的消息,並且基於消息。你需要谷歌來找出如何實現它,但它並不困難。 – hvgotcodes 2010-08-04 02:07:32

+0

我很感激。 – user377067 2010-08-04 02:10:19

相關問題