ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 10,TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000));
一、用一个list保存ThreadPoolExecutor submit的callable task所返回的Future对象:
List<Future<Object>> futureList...
threadPool.submit(new Callable(){...})
在主线程中遍历这个list并调用Future的get()方法取到Task的返回值:
for (Future<Object> future : futureList) {
future.get();
}
由于用submit的task不一定是按照加入自己维护的list顺序完成的,从list中遍历的每个Future对象并不一定处于完成状态,这时调用get()方法就会被阻塞住,这样对于处于list后面的但是先完成的线程就会增加了额外的等待时间。
所以,用list保存Future对象,先完成的不一定先被取出。
二、通过CompletionService包装ThreadPoolExecutor,然后调用其take()方法去取Future对象。
CompletionService<Object> completionService = new ExecutorCompletionService<Object>(threadPoolExecutor);
completionService.submit(new Callable(){...});
for(;;){
Future<Object> future=completionService.take();
}
而CompletionService的实现是维护一个保存Future对象的BlockingQueue。只有当这个Future对象状态是结束的时候,才会加入到这个Queue中,take()方法会从Queue中取出Future对象,如果Queue是空的,就会阻塞在那里,直到有完成的Future对象加入到Queue中。
所以,用CompletionService时,先完成的必定先被取出,这样就减少了不必要的等待时间。