2

現在、特定のJavaサーブレットの実装をスレッドセーフにする必要があります。コードは私が書いたものではなく、デザインなどにも関わっていませんでした。私はそれをスレッドセーフにする必要があります:)

私はスレッドセーフの初心者ではありませんが、専門家でもありません。サーブレットは(多かれ少なかれ)私にとって完全に新しいものです。私はいくつかのチュートリアルを実行し、サーブレットの基本を知っていますが、それだけです。サーブレットをスレッドセーフにすることについて私が見つけたすべてのチュートリアルはかなり表面的なものであり、まだ答えを見つけることができないように思われるいくつかの未回答の質問があります。いくつかの助けをいただければ幸いです。

1.)私が理解していることから、HttpServletRequestsとHttpServletResponsesは異なるスレッド間で共有されていないため、それらの読み取りアクセスと書き込みアクセスを同期する必要はありません(これは正しいですか?)。しかし、HttpServletRequestWrappersなどはどうですか?

2.)getServletContext()によって返されるServletContextオブジェクトへのアクセスを同期する必要があります。特に、setAttribute()を使用する場合はそうです。

3.)HttpServletRequestsにはgetCookies()メソッドがあります。これらのCookieは異なるリクエスト間で共有される可能性がありますか、それともすべてのリクエストに独自のCookieオブジェクトがありますか(同じ「実際の」Cookieを表す場合でも)?別の質問:返されたCookieオブジェクトへのアクセスを同期する必要がありますか?

私の質問を読むために時間を割いてくれてありがとう。私はあなたの答えを楽しみにしています:)

4

3 に答える 3

1
  1. Your understanding is correct. Actually thread is created for each request. So HttpServletRequest and HttpServletResponse are local to thread. So no sharing of these two. You do not need to synchronize them. HttpServletRequestWrapper and HttpServletResponseWrapper are the classes which provide a convenient implementation of the HttpServletRequest and HttpServletResponse interfaces respectively. You do not need to worry about them in synchronization context.

  2. Definitely you have to provide synchronization for ServletContext object returned by getServletContext() because it is shared between servlets in your application.

  3. As HttpServletRequest is local to thread created by container to serve the request. So cookies are also local to that thread and those are not shared. So no need to provide synchronization to cookies.

Few concepts :

  1. Servlets are always singlton in your application. i.e. only one object is created.
  2. For each request a different thread is created(actually obtained from Thread Pool). Following things are local to thread : HttpServletRequest, HttpServletResponse
于 2012-08-24T09:26:02.507 に答える
1

アプリケーションサーバーはサーブレットの単一インスタンスまたはインスタンスのプールを維持し、それらを複数の着信要求間で共有できるため、サーブレットはスレッドセーフではありません。したがって、サーブレットは状態を持たないようにする必要があります(つまり、サーブレットオブジェクトレベルの変数はスレッドセーフではありません)。サーブレット仕様は、SingleThreadModel以前は特定のサーブレットをスレッドセーフにするためのインターフェイスを備えていましたが、2.3以降は非推奨になっていると思います。

反応:

  1. そうです、これらはdoGetやdoPostなどのHTTPメソッドへのパラメーターであるため、これらへのアクセスを同期する必要はありません。

  2. getServletContext()は、特定のサーブレットを実行しているすべてのサーブレットとすべてのスレッドがアクセスできるコンテキストレベルのオブジェクトを返すためです。

  3. すべてのリクエストには、独自のCookieのセットが付属しています。繰り返しますが、これはメソッドパラメータHttpServletRequestから取得されるため、アクセスを同期する必要はありません。

于 2012-08-24T09:09:44.463 に答える
1

サーブレットをスレッドセーフにする場合、同期が必要になることはめったにありません。サーブレットの単一インスタンスが複数のユーザーによって使用される可能性があるため、サーブレットも最初からスレッドセーフである必要があります。さらに、サーブレットコンテナが常に1つだけであると指定しない限り、サーブレットのインスタンスが1つだけであると信頼することはできません。

1)一度に1つのスレッドしか要求を処理できないため、要求オブジェクトと応答オブジェクトを処理するときに同期する必要はありません。

2)サーブレット内のServletContextに値を設定する必要がないようにアプリケーションを設計する必要があります。通常、ServletContextは起動時に初期化され、サーブレットまたはフィルタによって読み取り専用として使用されます。スレッドセーフであるかどうかは正確にはわかりませんが、同じリクエストで複数の値を設定した場合は、それらの値を読み取るサーブレットが混乱しないように、とにかく同期する必要があります。しかし、これは基本的なスレッドセーフの問題であり、特にサーブレットとは関係ありません。

3)Cookieは現在の要求を処理し、1つのスレッドのみがそれを実行できるため、Cookieの同期は必要ありません。

新しいサーブレットコンテナでは、複数のスレッドが1つのリクエストを処理する可能性があるが、それでも一度に1つのスレッドである非同期モデルが可能です。

于 2012-08-24T09:23:13.830 に答える