我希望使用CompletionService处理一系列线程的结果,在它们完成时。我将服务放在循环中,以获取提供的Future对象,但是我不知道确定所有线程何时完成(从而退出循环)的最佳方法:
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
public class Bar {
final static int MAX_THREADS = 4;
final static int TOTAL_THREADS = 20;
public static void main(String[] args) throws Exception{
final ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(MAX_THREADS);
final CompletionService<Integer> service = new ExecutorCompletionService<Integer>(threadPool);
for (int i=0; i<TOTAL_THREADS; i++){
service.submit(new MyCallable(i));
}
int finished = 0;
Future<Integer> future = null;
do{
future = service.take();
int result = future.get();
System.out.println(" took: " + result);
finished++;
}while(finished < TOTAL_THREADS);
System.out.println("Shutting down");
threadPool.shutdown();
}
public static class MyCallable implements Callable<Integer>{
final int id;
public MyCallable(int id){
this.id = id;
System.out.println("Submitting: " + id);
}
@Override
public Integer call() throws Exception {
Thread.sleep(1000);
System.out.println("finished: " + id);
return id;
}
}
}
我尝试检查ThreadPoolExecutor的状态,但我知道getCompletedTaskCount和getTaskCount方法只是近似值,不能依赖它们。有没有更好的方法来确保我已经从CompletionService中检索到了所有的Futures,而不是自己计数?
编辑:Nobeh提供的链接和this link都建议计算提交的任务数,然后调用take()相同次数。我只是惊讶于没有一种方法可以询问CompletionService或其Executor还剩下什么需要返回。