3

典型的な Web アプリケーションでは、リクエストが来ると、フィルタは HTTP セッションで Context オブジェクトを探します。存在しない場合は、Context オブジェクトを作成し、http セッションに保存します。さらに、この Context オブジェクトは ThreadLocal オブジェクトにも格納されます。パスの下にあるサーブレットは、この Context オブジェクトを ThreadLocal から取得して変更します。応答が返されると、フィルターは ThreadLocal の Context オブジェクトを null にするようになりました。ユーザーが別のリクエストを行ったときに、変更された Context オブジェクトを確認できるでしょうか?

ありがとうQuadir

4

4 に答える 4

3

いいえ。null (またはより適切な呼び出しthreadLocal.remove()) の場合、値は失われます。

そうしないと、同じスレッドが割り当てられている次のリクエストの一部に表示される可能性があります (サーブレット コンテナーはスレッド プールを使用します)。しかし、これはスレッドプールの望ましくない副作用です。常にスレッドローカルを消去する必要があります。(こちらをご覧ください

于 2011-09-05T15:27:23.343 に答える
3

はい、Context オブジェクトへの参照が HttpSession に格納されているため、ユーザーには Context オブジェクトが表示されます。ThreadLocal 内の参照が null にされたとしても、2 番目の要求中にセッション内で引き続き検出されます。

編集: ThreadLocal の OpenJDK ソースコード(410 行目から) では、ThreadLocal の set メソッドと remove メソッドの違いを確認できます。set(null) を呼び出すと、ThreadLocalMap エントリは null 値でそのまま残りますが、remove() はそれを完全に削除します。あなたの質問に関しては違いはありません。セッションには Context オブジェクトへの参照がまだあります。

あなたの質問のタイトルを最初に読んだとき、HttpSessionやThreadLocalのクリアについて言及されていなかったため、別の解釈をしました。おそらく、これは一部の回答者を混乱させました。最初のリクエストで設定された (そしてクリアされていない) ThreadLocal 変数が 2 番目のリクエストでも引き続きアクセスできるかどうかを知りたいようです。答えは、これは Web サーバーがスレッドを処理する方法に依存するということだと思います。ランダムに再利用される 10 個のスレッドのスレッドプールがある場合、2 番目のリクエストで同じ ThreadLocal 変数が見つかる可能性は 10% です。

于 2011-09-05T16:24:36.813 に答える
1

いいえ - スレッド プールを使用していない限り、次のリクエストには表示されません。ただし、null にする代わりに、スレッド ローカル インスタンスで remove() を呼び出す方がよいでしょう。そうしないと、メモリ リークが発生する可能性があります。

于 2011-09-05T16:24:06.670 に答える
0

それは文脈に依存します。セッション コンテキストとアプリケーション コンテキストは明示的に復元されますが、リクエスト コンテキストとその他の ThreadLocals は、リクエスト間で持続するために絶対に依存することはできません。これは、同じスレッドが完全に異なるユーザーからのリクエストを処理できる (通常は処理する) ためです。一部の (すべてではないにしても) Web コンテナーは、意図的にすべての ThreadLocals を削除して、ユーザーが誤ってデータを共有するのを回避していると思います。

于 2011-09-05T15:27:55.320 に答える