2012-10-09 7 views
0

나는 자바 실행 프로그램을 사용하여 주어진 작업을 병렬로 처리하고 처리하고있다. 여러 가지 작업이있을 수 있습니다. 그것들은 모두 처음에 대기열에 놓이고 마스터 컨트롤러 객체는 모든 것이 끝날 때까지 대기합니다.여러 실행자 작업이 완료되면 master에게 알립니다.

내가 겪고있는 문제는 모든 작업이 완료된 시점을 결정하는 방법입니다. 하나의 큰 작업은 한 번에 모든 대기열에만 있기 때문에 (즉, 현재 대기중인 모든 작업이 모두 동일한 마스터 작업에 속함) getCompletedTaskCount() 메서드를 사용하여 완료된 작업의 수를 원래 대기중인 작업의 수와 비교할 수 있습니다.

그러나 이것은 필자가 완료된 작업 수에 대해 지속적으로 실행자를 폴링해야한다는 것을 요구하며, 내 의견으로는 그다지 해결책이 아닙니다.

while (pool.getCompletedTaskCount() - start_count < num_tasks) 
{ 
    try 
    { 
     Thread.sleep(30); 
    } 
    catch (InterruptedException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

내가 예상 작업의 수는 마스터 스레드를 통지에 카운트가 동등 다음 경우, 각 작업이 증가 할 수있는 카운터 개체를하는 것에 대한 생각했다.

마스터 스레드 :

counter_object.expected_count = num_tasks; 
counter_object.count = 0; 
queue_tasks(); 
synchronized(counter_object) 
{ 
    counter_object.wait(); 
} 
// all tasks have finished 

작업자 작업 :이 같은 뭔가 (없는 예외 핸들러와 같은 같은 다소 불완전 코드 무시)

// ...do task 
// task finished, update counter 
synchronized(counter_object) 
{ 
    ++counter_object.count; 
    if(counter_object.count == counter_object.expected_count) 
    { 
     // all tasks have finished, notify master thread 
     counter_object.notify(); 
    } 
} 

이 방법은 또한 추가 이점이를 그 I 카운터 개체가 주어진 마스터에 대해 로컬이기 때문에 단일 실행 프로그램을 사용하여 여러 마스터 작업을 실행할 수 있습니다.

이 문제를 해결하는 더 좋은 방법이 있습니까? 작업 수는 executor가 생성 할 수있는 최대 스레드 수보다 훨씬 클 수 있으므로 CyclicBarrier이 작동하지 않을 것이라고 생각합니다.

답변

2

이 글자는 ExecutorService.invokeAll과 같습니다. 또한

Collection<Callable> tasks = <get all sub tasks>; 
executorService.invokeAll(tasks); 
// Execution proceeds at the following line only once all "tasks" have been run 

(당신은 가능성이 Runnable 인스턴스가 아닌 Callable 다루고 있기 때문에, 당신은 ExecutorService.submit(Runnable)를 사용하고가 완료 될 때까지 기다립니다

for (Runnable task:tasks) { 
    futures.add(executorService.submit(task)); 
} 

for (Future<Void> result:futures) { 
    result.get(); 
} 

참고 :. 예외 처리

을 생략
관련 문제