2011-10-31 10 views
1

私は、ステートレスJavaアプリケーションをTomcat Webサーバーにデプロイしました。データの性質上、ある時点では、すべてのhttpスレッドが異なるキーを処理しなければなりません(つまり、すべてのスレッドが異なるキーを処理している必要があります)。JavaのTomcat特定のHTTPスレッドのみをキューに入れる方法は?

したがって、要求のキーが進行中であれば(これ以前のhttp投稿によって)、http投稿をキューに入れるモジュールを作成しました。私は、同じキーを持つ前のhttp投稿がプロセスを完了すると、現在のhttp投稿を処理し続けるだけです。

私は、進行中の同じキーで以前のリクエストがあるかどうかをテストするために、concurrenthashmapを使って単純なwhileループを書きました。パフォーマンスはサブパイルであり、予期しない動作があります。これは、コードスニペットです:それぞれのHTTP POSTの終わりに

//This part of code is place inside the servlet 
private static ConcurrentHashMap<String, String> transQueue = new ConcurrentHashMap<String, String>(); 
private void inQueuePoll(String queueKey) { 
    while(transQueue.containsKey(queueKey)){  
     synchronized(this){ 
     try{ 
      Thread.sleep(50); // i know this is bad, any idea to improve this? 
      logger.trace("Wait for Que Key: "+queueKey + "); 

      }catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
    transQueue.put(queueKey, ""); 
} 

、finallyブロックで、私は入れ:transQueue.remove(queueKey)私はConcurrentHashMapのからそれを削除持っていることを確認します。しかし、私の最悪の悪夢では、サーバーログから、私はqueueKey、別のhttpのポストスレッドを削除する前に、上記のwhileループを抜け出し、処理を続行することに気付きました。

上記のコードでhttpスレッドを「キューに入れる」に間違ったことはありますか?

また、私がこれをもっとうまくやっていく方法についてのアイデアは非常に高く評価されています。

答えて

0

まず、明確にするためにあなたのケースを再提示できる場合。任意のキーに対して、すべての要求は単一のスレッドで処理する必要があります。しかしながら、他のキーに対する要求は、第1のキーに対する要求が処理されるのと同時に処理することができる。

これは、ExecutorServiceのために私にぴったりのものです。マップを<String, ExecutorService>マップにします。ここでキーはキューキーで、値はシングルスレッドのエグゼキュータです(これはExecutors.newSingleThreadExecutor()で取得できます)。

キーを指定すると、マップからExecutorServiceを取得し、処理するCallableを送信します。このキーのExecutorはシングルスレッドなので、このキーが処理される前にそのキーの前回の要求が処理されるまで待つことが保証されます。 getへの呼び出しは、この要求の処理が完了するまでブロックします。

関連する問題