2010-05-11 597 views
15

當使用Java線程,一個必須採取的通過同步等Tomcat的線程和Java線程

AFAIK的Tomcat也與線程工作處理其工作量來併發的基本問題護理。爲什麼,我不需要考慮在Tomcat中運行代碼時線程安全問題?

回答

30

必須讓你的代碼在tomcat線程安全。 Tomcat會從多個線程調用您的代碼(即您的servlet),如果該代碼不是線程安全的,則會遇到問題。

Tomcat的線程與您自己創建的任何線程沒有區別。

+7

填寫你的答案: 例如,當你編寫一個servlet時,你不應該在servlet類中有局部變量。爲什麼?因爲servlet類沒有爲每個線程實例化。 Tomcat重用了多個線程的實例,所以你的所有變量都應該放在doGet或doPost方法中,所以每次調用方法時,它們都會被初始化並分配到不同的內存中。 – pakore 2010-05-11 12:11:42

+8

@pakore:局部變量是方法內部的變量。你的意思是實例變量。 – 2010-05-11 12:14:11

+1

是的,我的意思是實例變量。抱歉。感謝您的更正:)。 我現在無法編輯我的評論:( – pakore 2010-05-11 12:29:29

20

要添加到skaffman提到什麼,這似乎是你不需要編寫web應用程序時,考慮多線程,因爲Servlet的框架/ API是面向完全圍繞實現方法(service()doGet()doPost()等),每個HTTP請求調用一次。

因此,在一個簡單的應用程序中,您可以在您的servlet和/或JSP或其他任何應用程序中實現這些方法,而不用考慮多線程交互時會發生什麼。

但在開始第二個具有共享狀態的servlet或服務的方法之間,則可能沒有意識到它處理多個線程的互動,如果你不小心,你最終會擁有多線程或同步的問題。你將不得不處理這個問題,因爲在Tomcat中(我假定所有的servlet容器,儘管我不知道Servlet規範是否需要它),但每個請求都可能由不同的線程處理。因此,如果您收到兩個同時發出的請求,這些請求將同時由兩個單獨的線程處理(同時)。

1

因爲Java EE容器的編寫方式可以爲您處理線程。你寫你的代碼是線程安全的,容器完成剩下的工作。它彙集線程併爲它們分配一個請求。

4

如果您認爲Tomcat使您的應用程序線程安全,請使用可變成員變量(如非併發hashmap)編寫Servlet。

然後讓servlet爲每個請求放入哈希映射中的內容。獲得可愛的併發異常並不需要很長時間。

這就是爲什麼通常對於類似單身的組件,你必須非常小心的成員變量,因爲它們是在訪問該對象的多個線程之間共享的。

現在servlet容器爲每個請求(這是一些web應用程序框架所做的)創建一個新的瞬態對象,您可以將與該瞬變對象中的成員變量進行交互的行爲置爲線程安全。