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时,先完成的必定先被取出,这样就减少了不必要的等待时间。
本文介绍了如何使用CompletionService包装ThreadPoolExecutor来优化并发任务执行效率,避免了使用普通list保存Future对象带来的等待时间增加问题。通过遍历CompletionService的Future对象,可以确保先完成的任务先被取出,有效减少不必要的等待。
635

被折叠的 条评论
为什么被折叠?



