2016-09-29 6 views
2

Новичок здесь.Как я могу сделать много вызовов WS в отдельных потоках и увеличивать единую переменную результата?

Мне нужно выполнить действие Struts для получения некоторых данных путем многократного вызова веб-сервиса с различным запросом и ждать завершения каждого запроса, чтобы я мог отображать результат.

Поэтому в основном я делаю это так:

// 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 Я бы порекомендовал CompletableFuture

Это позволит создать нагрузку потоков, которые управляют асинхронным что-то вроде этого

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

После того, как вы создали все фьючерсы, вы можете проверить, когда все будет завершено.

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

Тогда для каждого из ваших фьючерсов вы можете сделать просуммировать значения

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

Большое спасибо за ваш ответ. К сожалению, я работаю над старым проектом, используя более старую версию Java (Java 6), поэтому я не могу использовать это решение ... Я буду помнить это для последующих целей! – Someday

0

Вы можете использовать Executor framework с CountDownLatch для этого. ExecutorService выполнит асинхронные задачи в пуле потоков, а CountDownLatch будет ждать завершения всех задач.

В этом случае вы должны учитывать, что countDownLatch.countDown(); должен быть представлен в блоке finally, поэтому он гарантированно будет выполнен, и на общую сумму вы должны использовать поточный сейф 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"); 

 Смежные вопросы

  • Нет связанных вопросов^_^