2016-09-29 6 views
2

スレッド初心者はこちら。WSコールを別々のスレッドで実行し、単一の結果変数をインクリメントするにはどうすればよいですか?

私はStrutsアクションで毎回異なるリクエストで何度もWebサービスを呼び出してデータを取得し、すべてのリクエストが完了するのを待って結果を表示できるようにする必要があります。

だから、基本的に私はこのようにそれをやっている:

// The list of the region codes used for the requests 
List<String> codesRegions; 

// Init of a variable containing the total amount of data 
Integer totalAmount = 0; 

// For every region 
for(String codeRegion : codesRegions) 
{ 
    MyRegionStub stub = createRegionStub(); 

    // Call of the WS with the code region 
    MyRegionRequest request = new MyRegionRequest(); 
    request.setCodeRegion(codeRegion); 

    // Getting the number associated to the region and incrementing totalAmount 
    MyRegionResponse response = stub.getRegionStats(request); 
    totalAmount += response.getRegionStats(); 
} 

// Once all the calls are done, I display the result 
request.setAttribute("totalAmount", totalAmount); 
mapping.findForward("success"); 

私の問題は、私は多くの場合、私はこのWSに多くの時間を呼び出していて、これを行うことで、タイムアウトエラーが出るということです。だから私は別のスレッドでどのようにすべての呼び出しを行うことができ、何の間違いもなく同じ結果変数をインクリメントできることを知りたい。

私が知りたいことは、データを表示するためにすべての呼び出しが完了するまで待つ必要があることです。これが完了した場合にのみmapping.findForward("success");に電話するには何が必要ですか?

答えて

1

は、Java 8を使用している場合、私は、これはあなたが未来のすべてを作成したら、この

CompleteableFuture<Integer> future CompleteableFuture.supplyAsync(getRegionStats(codeRegion)) 

のような非同期な何かを実行するスレッドの負荷を作成することができますCompletableFuture

をお勧めしますすべて完了した時点を確認することができます。

CompleteableFuture.allOf(future1, future2).join(); 

次に、あなたの未来のそれぞれについて、あなたはこのためCountDownLatchExecutor frameworkを使用することができます値

for(CompleteableFuture future : futures) 
     totalAmount+= future.get() 
+0

は、あなたの答えをありがとうございました。残念ながら、古いバージョンのJava(Java 6)を使用している古いプロジェクトで作業していますので、このソリューションを使用することはできません。 – Someday

0

を合計行うことができます。 ExecutorServiceはスレッドプールで非同期タスクを実行し、CountDownLatchはすべてのタスクの完了を待機します。

この場合、finallyブロックにはcountDownLatch.countDown();が存在する必要があるので、実行が保証されており、合計金額でスレッドセーフAtomicIntegerを使用する必要があります。

あなたのコードは次のようになります。

ExecutorService threadPool = Executors.newFixedThreadPool(10); 
CountDownLatch countDownLatch = new CountDownLatch(codesRegions.size()); 
AtomicInteger totalAmount = new AtomicInteger(0); 

for (String codeRegion : codesRegions) 
{ 
    threadPool.execute(new Runnable() { 

     @Override 
     public void run() 
     { 
      try 
      { 
       MyRegionStub stub = createRegionStub(); 

       // Call of the WS with the code region 
       MyRegionRequest request = new MyRegionRequest(); 
       request.setCodeRegion(codeRegion); 

       // Getting the number associated to the region and 
       // incrementing 
       // totalAmount 
       MyRegionResponse response = stub.getRegionStats(request); 
       totalAmount.addAndGet(response.getRegionStats()); 
      } 
      finally 
      { 
       countDownLatch.countDown(); 
      } 
     } 
    }); 
} 
try 
{ 
    countDownLatch.await(); 
} 
catch (InterruptedException e) 
{ 
    //Return ERROR in case of current thread is interrupted. 
} 
// Once all the calls are done, I display the result 
request.setAttribute("totalAmount", totalAmount); 
mapping.findForward("success"); 
関連する問題