2012-08-24 24 views
2

我目前必須使線程安全的特定Java servlet實現。代碼不是由我寫的,我沒有涉及它的設計或任何其他東西。我「只是」必須使它線程安全的:)有關Java Servlets的詳細線程安全問題

我不是線程安全初學者,但不是專業無論是。 Servlets(或多或少)對我來說是全新的。我已經完成了一些教程並瞭解了有關servlet的基礎知識,但就是這樣。我可以找到有關使servlet線程安全的所有教程都很膚淺,我仍然有一些未解答的問題,我似乎無法找到答案。一些幫助將不勝感激。

1.)據我所知,HttpServletRequests和HttpServletResponses不是在不同的線程之間共享的,所以我不需要在它們上同步讀寫訪問(這是否正確?)。但是HttpServletRequestWrappers等呢?

2.)我必須同步訪問由getServletContext()返回的ServletContext對象,特別是如果我使用setAttribute()對吧?

3.)HttpServletRequests有一個getCookies()方法。這些Cookie可能在不同請求之間共享,或者每個請求是否擁有自己的Cookie對象(即使它們代表相同的「真實」cookie)?以不同的方式提問:我是否必須同步對返回的cookie對象的訪問?

感謝您花時間閱讀我的問題。我期待着你的答案:)

回答

1

的Servlet不是線程安全的,因爲應用服務器可以保持servlet或實例池的單個實例並在多個傳入的請求共享。因此,servlet不應該有任何狀態(即servlet對象級變量不是線程安全的)。 Servlet規範以前有SingleThreadModel接口來強制給定的servlet是線程安全的,但從2.3開始已經棄用了,我想。

對策:

  1. 權,這些都是paramters到HTTP方法等的doGet和doPost並因此訪問這些不需要同步。

  2. 正確的,因爲getServletContext()方法返回一個上下文級的對象是所有的servlet和運行這個servlet的所有線程訪問。

  3. 每個請求都附帶自己的一組cookie。同樣,這是從方法參數HttpServletRequest獲得的,因此訪問不需要同步。

1

當你讓servlets線程安全時,你很少需要同步。 Servlets也應該從頭開始是線程安全的,因爲單個servlet實例可能會被多個用戶使用。另外,你不能相信只有一個servlet實例,除非你的servlet容器指定總是隻有一個實例。

1)與請求和響應對象處理,因爲只有一個線程可以同時處理的請求時,不需要進行同步。

2)你應該嘗試在你沒有在ServletContext中設置一個servlet內的任何值的方式來設計應用程序。通常,ServletContext在啓動時被初始化,然後被servlet或過濾器用作只讀。我不確定它是否應該是線程安全的,但是如果您在同一請求中設置了多個值,則必須同步,以便讀取這些值的servlet不會混亂。但這是基本的線程安全問題,並不特別與servlet有關。

3)不需要同步cookie,因爲它們處理當前的請求,只有一個線程可以做到這一點。

新的servlet容器允許異步模型,其中多個線程可以處理單個請求,但它仍然是一次一個線程。

1
  1. 你的理解是正確的。實際上,線程是爲每個請求創建的。所以HttpServletRequestHttpServletResponse是本地線程。所以不要分享這兩個。你不需要同步它們。 HttpServletRequestWrapperHttpServletResponseWrapper是分別提供了一個方便的實現接口的類。您不需要在同步上下文中擔心它們。

  2. 當然,您必須爲ServletContext object returned by getServletContext()提供同步,因爲它在應用程序中的servlet之間共享。

  3. 由於HttpServletRequest是由容器創建的線程的局部,以便爲請求提供服務。所以cookie也是該線程的本地,並且這些不共享。所以不需要提供與cookies的同步。

幾個概念:

  1. 應用程序中Servlet總是singlton。即僅創建一個對象。
  2. 對於每個請求,創建一個不同的線程(實際上從線程池獲得)。以下是本地線程:HttpServletRequest,HttpServletResponse