4

우리는 한 가지 방법으로 약 15 회의 다른 webservice 호출을해야하는 stipes (java) 웹 애플리케이션을 가지고 있습니다. 예를 들어 : ... Webapp에서 다른 웹 서비스 호출하기

public Resolution userProfile() 
    { 
     serviceOneCall(); 
     serviceTwoCall(); 
     serviceThreeCall(); 
     serviceFourCall(); 
     .... 
     serviceTenCall(); 

     return new RedirectResolution("profiel.jsp"); 
    } 

이 모든

병렬로 불리는 서로에 의존하지 않는 수 있습니다. 이러한 호출의 대부분이하는 일은 세션에 데이터를 넣는 것입니다. 하나 또는 두 개는 세션에있는 동일한 객체에 데이터를 넣을 수 있으므로 스레드 안전이 걱정 될 수 있습니다.

누구나 동시에 이들 모두를 호출하는 좋은 방법을 제안 할 수 있습니까?

답변

5

이 작업을 병렬로 수행하는 모든 솔루션은 새 스레드를 생성하거나 원격 네트워크 호출이 발생하도록 스레드 풀에 작업을 제출하는 작업을 포함하게됩니다.

스레드 안전 문제를 방지하는 좋은 방법은 응답 값을 돌려주기 executorService를 사용하고 Callable<T> (하나의 submit(Callable) 또는 invokeAll(Collection<Callable>) 방법)의 서브 클래스를 제출하고 Callables하는 것입니다. 이렇게하면 초기 메서드가 각 호출의 반환 값을 처리하고 세션에서 응답을 설정하거나 다른 스레드에서 발생하는이 작업 대신 다른 개체를 업데이트하도록 선택할 수 있습니다.

그래서 기본 알고리즘 :

  1. Future<T> 당신이 때까지 차단하기 위해 각각의 ExecutorService를
  2. 전화 Future.get()에서 돌아 오기의 수집 Callable<T> 서브 클래스
  3. 에 ExecutorService를 이러한 호출을 각각 제출 응답을 처리 한 다음 응답을 처리하지만 기본 스레드에서 다시 원할 경우
+0

당신은 여전히 ​​공통 세션 객체를 동기화해야합니다. – Geek

-2
for (i = 0; i <= numOfServiceCalls; i++) { 
    new Thread(new Runnable() { 
     switch(i) { 
      case 1 : serviceOneCall(); 
        break(); 
      case 2 : serviceTwoCall(); 
        break(); 
      // Keep going with as many cases as you have. 
     } 
    }); 
} 
5

각 당신이 전화하고, 동시 변경을 기회가있을 때 업데이트되는 개체에 동기화해야 WS에 대한 Callable의 제출 스레드 풀을 가진 ExecutorService을 사용합니다.

당신은 당신이 단 하나의 get()이 모든 해답을 기다려야 할 필요가 있도록하는 Future<List<T>>List<Future<T>> 변환합니다 예를 Futures.allAsList()에 대한 사용하여 Future의의 쉬운 관리를 위해 Guava's 동시 확장을 사용할 수 있습니다.

+1

와우, Futures.allAsList() is pretty swee t –

+0

@mattb 전체 패키지는 실제로 : ListeningExecutorService, ListenableFuture' 및'Futures'는 비동기 호출을 연결하고 콜백을 할 수 있습니다. –

관련 문제