Submit는 작업 완료시 대기하는 데 사용할 수있는 Future 개체를 반환합니다. 이러한 작업을 추적하고 모든 하위 작업이 완료 될 때까지 반복적으로 차단하는 메서드를 추가 할 수 있습니다. 이렇게하면 필요한 곳에서 실행 프로그램을 재사용 할 수 있습니다.
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
public class JobExecutor {
ExecutorService executorService = Executors.newFixedThreadPool(1);
private class Task implements Runnable {
private final String name;
private final Task[] subtasks;
private final ExecutorService executorService;
private volatile boolean started = false;
private Future<?> taskFuture;
// Separate list from subtasks because this is what you'll probably
// actually use as you may not be passing subtasks as constructor args
private final List<Task> subtasksToWaitOn = new ArrayList<Task>();
public Task(String name, ExecutorService executorService,
Task... subtasks) {
this.name = name;
this.executorService = executorService;
this.subtasks = subtasks;
}
public synchronized void start() {
if (!started) {
started = true;
taskFuture = executorService.submit(this);
}
}
public synchronized void blockTillDone() {
if (started) {
try {
taskFuture.get();
} catch (InterruptedException e) {
// TODO Handle
} catch (ExecutionException e) {
// TODO Handle
}
for (Task subtaskToWaitOn : subtasksToWaitOn) {
subtaskToWaitOn.blockTillDone();
}
} else {
// TODO throw exception
}
}
@Override
public void run() {
for (Task subtask : subtasks) {
subtask.start();
subtasksToWaitOn.add(subtask);
}
System.out.println("My name is: " + name);
}
}
void testSubmit() {
Task subsubTask1 = new Task("Subsubtask1", executorService);
Task subtask1 = new Task("Subtask1", executorService, subsubTask1);
Task subtask2 = new Task("Subtask2", executorService);
Task subtask3 = new Task("Subtask3", executorService);
Task job = new Task("Job", executorService, subtask1, subtask2,
subtask3);
job.start();
job.blockTillDone();
System.out.println("Job done!");
}
public static void main(String[] args) {
new JobExecutor().testSubmit();
}
}
인쇄 아웃 :
당신이합니다 (백 포트 라이브러리
http://www.cs.washington.edu/homes/djg/teachingMaterials/grossmanSPAC_forkJoinFramework.html 또는 java6) java7에 경우
My name is: Job
My name is: Subtask1
My name is: Subtask2
My name is: Subtask3
My name is: Subsubtask1
Job done!
['CompletionService'] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CompletionService.html)을 검토 했습니까? ['submit'] (http://goo.gl/lmHAP)에 'Job'이 완료 됨과 연결된 값을 사용할 수 있습니다. – oldrinb
샘플 코드는 [ExecutorCompletionService의 javadoc] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorCompletionService.html)을 참조하십시오. – assylias
'CompletionService'를 살펴 봤지만 개별 결과 처리에 신경 쓰지 않아서 원하는 바가 아닌 것 같았습니다. 모두 완료되었을 때를 알고 싶습니다. 그래서 poll()/take() 하나 하나 지저분 해 보였습니다, 나는 단지 completionQueue가 언제 비어 있는지 알고 싶습니다. 어쩌면 나는 그것을 나의 목적을 위해 확장하는 것을보아야한다. – Brian