2012-03-12 15 views
4

サーブレットへのリクエストごとに、doPost()メソッドまたはdoGet()メソッドが実行され、initしかし、これらの方法の外に書かれたコードはどうですか?
このコードもスレッド化されていますか?その部分で宣言された変数は、doPost()で変更されていれば、その変更は他の要求に対してサーブレットに反映されますか?サーブレット内のinit()メソッドの外側で宣言された変数

答えて

5

通常のサーブレット・コンテナでは、サーブレット・オブジェクトのインスタンスは1つのみです。このオブジェクトは任意の数のスレッド(要求ごとに1つのスレッド)で使用できます。サーブレットインスタンスのライフタイムの管理は、サーブレットコンテナに依存します。

したがって、どのメソッド(init()も含む)でクラス変数の値を変更すると、後続のすべての要求に影響します。 メソッド内のローカル変数を変更または宣言しても、次回メソッドが呼び出されるときにローカル変数が再度作成されるため、何も影響しません(メソッドが終了するとガベージコレクタによって破棄されます)。

1

サーブレットインスタンスがコンテナによってプールされます。したがって、実世界のシナリオでは、任意の数のスレッドで任意の数のサーブレットオブジェクトを共有できます。すべてのdoXXX()メソッドおよびそれらから呼び出される他のメソッドは、スレッドによって共有されます。

したがって、サーブレットではクラスレベルの変数(状態を維持するため)を持つことをお勧めします。確かにConstants、Staticヘルパメソッドと静的変数を持つことはできますが、インスタンスによって共有され、サーブレットを使用するクライアントによって絶えず変更されることはありません。

しかし、物事はお勧めしませんが、変数/メソッドを同期させることを止めることはありません。これにより、一度に1つのスレッドだけがリソースにアクセスすることが保証されますが、スレッドがロックを占有する前に他のスレッドがリソースを解放するのを待たなければならないため、パフォーマンス上のペナルティが発生します。

しかし、より良い方法があります。サーブレットで状態を維持し、クライアントごとに変数を格納したい場合、サーブレットはjavax.servlet.SingleThreadModelを実装する必要があります。サーブレットがこのマーカーインターフェイスを実装している場合、コンテナは状態を維持しているため、インスタンスごとに1つのスレッドしか提供されません。

+0

javax.servlet.SingleThreadModelは推奨されていません。 –

関連する問題