セッションでサーブレットをスレッドセーフにしようとしています。同期ブロック、AtomicReference、ConcurrentHashMap などのさまざまな手法について調べました。ある場合、各手法のトレードオフは何ですか?
3 に答える
サーブレットの最初の目的は、状態を共有しないことでスレッド セーフを実現することです。サーブレットがロード バランシング クラスタにデプロイされた場合、どのような共有状態も失敗します。したがって、共有状態がキャッシュフレーバーではない場合、つまり永続的なストアからいつでも再構築できる場合は、そもそもそれを使用するべきではありません。
ただし、これらの懸念は別として、共有状態で解決しようとしている問題の詳細を説明せずに、万能の回答を得ることはできません。あなたが言及したすべてのテクニックにはメリットがあります。そのため、Java で 15 年の経験を積んだ後も、それらのテクニックは私たちと共にあります。
サーブレットは、状態、つまり、要求処理メソッドによって影響を受けるインスタンスまたは静的変数を持つべきではありません (さらに、その要求処理メソッドは、共有オブジェクトの状態に影響を与えるべきではありません)。サーブレット コンテナーごとに 1 つのサーブレット インスタンスしかなく、各要求は、適切なサーブレット メソッド (より一般的には doGet() または doPost()) を実行する新しいスレッドを使用して処理されます。
ただし、サーブレット API は、特定のユーザー セッションに関するデータをスレッド セーフな方法で保存するために必要なすべての機能を提供します。たとえば、HttpServletRequest#getSession() でセッションを取得し、その setAttribute() メソッドを使用して特定のセッションにオブジェクトを格納し、getAttribute() を使用して同じセッションの別のリクエストでオブジェクトを取得できます。
お役に立てれば。
まず第一に、サーブレットはステートレスである必要があります。これは、アプリケーションのスケーラビリティに適しています。実際、サーブレット API に基づくセッション オブジェクトは拡張性が高く、独自の HttpSession 実装を記述して、セッション アクセスをスレッドセーフにすることができます。IMHO、上記のデータ構造では、最後の2つはセッションのスレッドセーフアクセスとは何の関係もないように見えるため、シナリオの詳細を提供する必要があります。