web-dev-qa-db-ja.com

Java Webアプリケーションで「スレッドセーフティ」に注意する必要がありますか

スレッドセーフの意味については一般的に理解していますが、Java Webアプリケーションのコンテキストではスレッドについてはあまり知りません。スレッドセーフについて心配する必要があることを知りたくて、 Webアプリケーションでの作業中。

「スレッドの安全性」を気にせずにコードを記述した場合、Webアプリケーションで問題が発生する可能性はありますか?スレッドセーフなコレクションを使用しているかどうかを考慮する必要がありますか?

4
abhijeet

はい、確かにそうです:)ほとんど(すべて?)のJEE Webコンテナーは、複数のスレッドを同時に使用してクラスを実行します。また、Spring MVCなどのフレームワークは、シングルトンクラスインスタンスを使用してすべてのスレッドにサービスを提供します。ただし、いくつかの簡単なガイドラインに従うと、コードがスレッドセーフになります。

  • ユーザーに属するデータをシングルトンクラス(通常はコントローラーとバリデーター)のメンバー変数に格納することはできません。ユーザーデータはモデルに属し、モデルはユーザー固有である必要があります。
  • 複数のスレッドがアクセスするのでない限り、スレッドセーフなコレクションなどについて心配する必要はありません。これは、Webアプリケーションでは珍しいことです。たとえば、「ログインしたユーザー」コレクションのようなものはスレッドセーフである必要がありますが、ユーザー個人の値のリストはそうである必要はありません。
  • メソッドの呼び出しごとに自動的に新しい変数が割り当てられるため、メソッド内で宣言されたローカル変数はスレッドセーフである必要はありません。
  • Webフレームワークが「セッションで同期」機能を提供している場合(Spring MVCが提供します)、これをオンにすることをお勧めします。これは、ユーザーが送信を2回続けてすばやく押すと、最初の送信が2番目の開始前に実行を終了することを意味します。これにより、インテリジェントに処理する機会が得られます。これがないと、2つのスレッドがユーザーのデータ構造を争って、奇妙な結果が保証される可能性があります。
  • グローバルデータ構造へのアクセスは、スレッドの問題を考慮して設計する必要があります。たとえば、データベースから読み取られた値のキャッシュは、必ずスレッドセーフである必要があります。
  • 中間ストレージにファイルを使用しないでください。ファイルへのマルチスレッド書き込みは同期が難しく、複数のJVMが同じファイルに書き込みを行っている場合はほとんど不可能です(「サーバーファーム」またはクラスターインストールで発生する可能性があります)。これが必要な場合は、データベースを使用してください。トランザクション制御がはるかに簡単です。
  • 複数のユーザーが同じデータを更新できる特殊なケースが発生します。ただし、これはスレッドの問題ではありません。Googleで「長時間実行トランザクション」を試してください。それはかなりの話題です。

だから、はい、あなたはスレッドを認識する必要がありますが、実際にはそれは大きな問題ではありません。

8
kiwiron

はい。

すべてのHTTPリクエスト(サーブレット、JSPなどで処理されます)は別のスレッドで処理されるため、ランタイム条件の完全なセットを期待できます。

例として、アイテムのリストを保持してそれを反復処理する場合、同時に別のサーブレットがリストにアイテムを追加または削除すると、ConcurrentModificationException

サーブレットまたはステートレスEJBでインスタンス化されたオブジェクトのみを使用することで、これを最小限に抑えることができます。ただし、これを使用しても、DBトランザクションを正しく設計しないと、データの不整合が発生する可能性があります。

1
SJuan76