ThreadLocal を Web アプリケーションのデータのコンテキストとして使用することは良い考えですか?
5 に答える
それはデータの範囲に依存します。ThreadLocalは、ユーザーのセッションに固有ではなく、要求スレッドに固有になります(各要求、異なる要求処理スレッドが使用される場合があります)。したがって、リクエスト処理の完了時にデータを削除することが重要になります(同じスレッドがリクエストを処理するときに、他のユーザーのセッションにデータがブリードオーバーしないようにするため)。
そのために作られました。ただし、コンテキストの最後にある ThreadLocal を削除するように注意してください。そうしないと、メモリ リークが発生したり、少なくとも未使用のデータを長時間保持したりする可能性があります。
ThreadLocals も非常に高速です。HashMap<Thread,Object>
常に で照会される と考えることができますThread.getCurrentThread()
。
単一のスレッドで要求/応答のペアを完了する場合、私の経験では問題なく機能します。ただし、「イベント駆動型」Webアプリは、ajaxおよび高性能コンテナーの台頭とともに流行し始めています。これらのイベント駆動型モデルでは、たとえばI / Oイベント中に要求スレッドをスレッドプールに戻すことができるため、外部サービス呼び出しが戻るのを待ってスレッドが占有されることはありません。その結果、単一の論理要求が複数の異なるスレッドによって処理される場合があります。サーバー側のNIOと組み合わせたイベント駆動型アーキテクチャにより、スループットが大幅に向上します。
そうは言っても、アプリケーションにこのアーキテクチャがない場合は、私には合理的と思われます。
このモデルに慣れていない場合は、Tomcat6の「comet」とJetty6のContinuationsをご覧ください。これらは、公式のサーブレット3.0サポートが保留されている非同期I/Oのベンダー固有の実装です。現在、Tomcat7は完全に3.0に準拠していると主張していることに注意してください。
ThreadLocal
マルチスレッド プログラムの は、非スレッド プログラムの static/global とほとんど同じです。つまり、の使用はThreadLocal
忌まわしいものです。
一般的に、私はノーと言うでしょう。フレームワークを使用してそれを行います。
Web アプリケーションの Web 層では、セッション コンテキスト (またはその他の最上位のフレームワーク固有のコンテキスト) を使用して、要求範囲にわたってデータと状態を格納します。
ビジネス層を導入する場合、もちろん特定の Web コンテキストに依存するべきではありません。コンテキストとしてセキュリティ、トランザクション、永続化のソリューションを提供しますspring
。Java EE
手動でこれに触れる場合は、十分に注意する必要があります。クリーンアップの問題、メモリリーク、奇妙なバグにつながる可能性があります...