0

現在のスレッドがどのWebサイトコンテキストにあるかを設定および取得するために呼び出すことができる「マネージャー」をWebアプリに実装しています(Webサイトコンテキストが現在のサイトを表すように、サイトにホワイトラベルを付けます)

私はこれを行うための最良の戦略を見つけようとしています。現在、同時ハッシュマップでWebSiteContextsへのスレッドのストアを実装しています。

private final ConcurrentHashMap<Thread, WebSiteContext> chm = new ConcurrentHashMap<Thread, WebSiteContext>();

スレッドの開始時に(サーブレットフィルタを介して、または手動で設定することにより)、スレッドはそのWebSiteContextに関連付けられます。

ただし、メモリリークを回避するために、マップをクリーンアップする必要があります。したがって、1つの戦略は、マップのスレッドキーを繰り返し処理して、スレッドが「生きている」かどうかを確認し(thread.isAlive())、そうでない場合は、たとえば次のように削除することだと思います。

 public class Cleaner implements Runnable {
      private static final int INTERVAL = 6 * 1000; // 6 seconds
      public Cleaner() {
      }
      public void run() {
            // soo every interval iterate through the threads if they're dead then remove it from the map.
            while(true) {
               try {
                     Set<Thread> threads = chm.keySet();
                     Set<Thread> staleThreads = new HashSet<Thread>();
                     for (Thread tmpThread : threads) {

                        // if we get to a dead thread then clean the fucker up
                        if (!tmpThread.isAlive()) {
                           // think that we're going to get a run condition anyway
                           chm.remove(tmpThread);
                        }
                     }
                  Thread.sleep(INTERVAL);
               } catch (Exception e) {
                  log.error("caught exception e:", e);
               }
            }
      }
   }

、しかし、これは私が避けたいものであるマップへのアクセスを同期する必要があると思います(またはそうしますか?)。

Javaのスレッドに属性を格納したり、実際にスレッドオブジェクトをキーとして持つマップをクリーンアップしたりするための「慣用的な」パターンはありますか?私はWeakReference/SoftReferencesを使用することにオープンです。実際、Thread.getCurrentThread()。setAttribute(Object、Object)に相当するものがある場合は、それは素晴らしいことです。

乾杯サイモンB

4

4 に答える 4

2

考えたことはありThreadLocalますか?

于 2009-11-02T12:56:57.977 に答える
1

あなたのアプローチはうまくいくかもしれませんが、あなたは必要以上の仕事をすることになります。ThreadLocalはあなたが探しているものです。これにより、アプリケーションの各スレッドに関連するオブジェクトを保存できるようになります。これを使用する一般的な方法は、最初の値を割り当てるinitialValue()メソッドを実装することです。例:

 private static final ThreadLocal<String> localAttribute = new ThreadLocal<String> () {
         protected Integer initialValue() {
             return "InitialValue";
     }
 };

これにより、localAttribute.get()を最初に呼び出したときに、初期値が「InitialValue」の新しいスレッドローカルが提供されます。次に、localAttribute.set()を呼び出して、別の値を割り当てることができます。各リクエスタースレッドは、同じ属性に対して異なる値を持ちます。

ThreadLocalを使用することの良い点は、スレッドが停止したときに、ローカルスレッドがデータをガベージコレクションに使用できるようにする必要があることです。

于 2009-11-02T13:04:52.110 に答える
0

1回のサーブレット呼び出しの間、「スレッドローカル」変数スペースを定義します。ここでの最善の方法は、追加したのと同じレベルでマッピングを削除することです。したがって、マップに追加する場合は、途中でマッピングを削除しServletFilterたブロックを追加します。finallyサーブレットでの「手動」追加についても同じことが言えます。

別の方法として、この情報をユーザーに含めるServletContextか、属性として追加しThreadLocalます。

于 2009-11-02T13:04:36.540 に答える
0
  • java.lang.ThreadLocal ;
  • ターゲット情報をサーブレットリクエスト属性にバインドします。
于 2009-11-02T12:57:48.433 に答える