2

いくつか質問があります。私の知る限り、コンテナへのすべてのリクエストはHttpServletRequest. より多くのリクエスト -> のより多くのインスタンスHttpServletRequest。次に、リクエスト オブジェクトが「abc」という名前のサーブレットを呼び出すと、「abc」サーブレットのインスタンスが作成されます。同時に 3 つのリクエストが「abc」サーブレットに送信された場合、
(1)知りたいのですが、各リクエストごとに「abc」サーブレットの 3 つのインスタンスが作成されるということですか? または、サーブレットへの 1 つの要求が完了するまで要求がキューに入れられます。

次に、「abc」サーブレットへの 3 つの要求が、挿入と検索を同時に実行できるいくつかのデータベース プロセスを実行するとします。次に、
(2)他のリクエストのサーブレットがタスクを完了する(同期する)まで、またはすべてのサーブレットが個別のタスクとしてマルチスレッドとしてDBタスクを実行する(同期しない)まで、1つのリクエストをキューに入れる必要がありますか?
(3)。それらが同期されていない場合、それらのタスクを同期させて (たとえば、特定のタスクを 1 つだけ DB に保存するなど)、キューに入れるにはどうすればよいでしょうか? そのためには、サーブレットを実装するSingleThreadModelか、シングルトン パターンに従って作成されたクラスにあるメソッドを使用する方がよいでしょうか? それでは、コンテナのパフォーマンスにどのように影響しますか?

つまり、すべてのリクエストに対して同期された特定のタスクを実行するにはどうすればよいでしょうか?

これも読みました。その記事はサーブレットについて述べています。サーブレットのタスクが別のクラスに引き渡されたとしましょう。これでシングルトン パターンを使用する方法を知りたいですか?

4

3 に答える 3

4

コンテナーは、サーブレット インスタンスのプールを作成する場合があります (以下のサーブレット仕様からの抜粋で詳細が説明されています)。3 つの同時要求に対して 3 つの異なるインスタンスを使用することも、3 つすべてに対して 1 つのインスタンスを使用することもあります。したがって、サーブレットはスレッド セーフである必要があり、メンバー変数に状態を含めるべきではありません。のSingleThreadModelマーカー インターフェイスは、複数の同時要求に対してサーブレットの同じインスタンスを使用しないようにコンテナーに通知します (したがって、サーブレットをスレッドセーフにします) が、コンテナーが複数のインスタンスを作成して同時に使用することを妨げません。理にかなっていますか?操作に同期が必要な場合は、コントローラーではなく、モデル クラスで処理します。したがって、基本的には他の場所で同期する (またはキューに入れる) ことが答えです。サーブレットにコマンドを受け取ってもらい、プロセスについてあまり考えずにそのまま実行させます。

更新します。あなたの場合の明示的な操作の同期の非常に基本的な例(私が好きというわけではありませんが、要点を説明するためだけです)は、メインdo()メソッドがsynchronized. ただし、理想的には、データベースの同時実行性をデータベースと永続レイヤー (トランザクション、楽観的同時実行性) に委譲します。

サーブレット仕様による訂正:

In the default case of a servlet not implementing SingleThreadModel and not hosted in a
distributed environment, the servlet container must use only one instance of a servlet class
per servlet definition.
In the case of a servlet that implements the SingleThreadModel interface, the servlet
container may instantiate multiple instances of that servlet so that it can handle a heavy
request load while still serializing requests to a single instance.

そうは言っても、シングル スレッド モデル マーカーを使用しない限り、サーブレットのインスタンスは 1 つしかありません。

于 2012-04-23T18:01:21.483 に答える
1
1) No, only instance of servlet exists per server
2) No, each request is separate thread

サーバーにインスタンス変数 (または) 静的変数を含めることはできません。各スレッドにはローカル変数と実行シーケンスの独自のコピーがあるため、同期は問題になりません。

3) synch ブロックの助けを借りて、doGet() メソッドと doPost() メソッドの同期を前に付けることで、サーブレットを同期させることができます。しかし、それは悪い習慣です。

完全な説明については、このSO Wiki リンクを参照してください。

于 2012-04-23T18:02:22.273 に答える
0

特定のタスクを同期するには、2 つの方法を提案させてください。

  1. Javasynchronizedブロックを使用します。ロック オブジェクトに適したオブジェクトを検討する必要があります。
  2. データベース ロックを使用します。そのようなselect * from xxx for update
于 2012-04-23T18:07:18.863 に答える