当通过ExecutorCompletionService执行任务时,任务是否并行化?
问题描述:
我提交了5个工作到ExecutorCompletionService,但它好像像工作顺序执行。传递给ExecutorCompletionService的构造函数的ExecutorService是使用newCacheThreadPool表单创建的。我做错了什么?当通过ExecutorCompletionService执行任务时,任务是否并行化?
UPDATE每个工作基本上都在做数据库查询&的一些计算。 ExecutorCompletionService的代码被取消为javadoc。我用自己的Callable实现替换了Callables。
答
ExecutorCompletionService
有什么都没有与作业执行方式有关,它只是检索结果的简便方法。
Executors.newCachedThreadPool
默认执行在单独的线程,这可以是并行任务,因为:
- 任务是独立的,并且不例如在同一个对象内同步;
- 你有多个硬件CPU线程。
最后一点值得解释。尽管没有任何保证,但实际上Sun JVM支持当前正在执行的线程,因此它永远不会换成另一个线程。这意味着你的5个任务可能由于JVM实现而最终被串行执行,一台多核机器。
答
执行将取决于许多事情。例如:
- 的时间长度,以便完成工作
- 在线程池中的线程(如果认为他们需要一个缓存的线程池只会创建线程)数量
按顺序执行并不一定是错误的。
答
每个工作基本上都在做数据库查询&的一些计算。 ExecutorCompletionService的代码被取消为javadoc。我用自己的Callable实现替换了Callables。
在这种情况下,你确定你不是想错了,他们是执行顺序,因为你检索结果顺序?
扔在你的可调用某些调试日志行排除这个可能性,和/或看看这有限的使用场景:
public static void main(String... args) throws InterruptedException, ExecutionException {
List<Callable<String>> list = new ArrayList<Callable<String>>();
list.add(new PowersOfX(2));
list.add(new PowersOfX(3));
list.add(new PowersOfX(5));
solve(Executors.newCachedThreadPool(), list);
}
static void solve(Executor e, Collection<Callable<String>> solvers) throws InterruptedException, ExecutionException {
CompletionService<String> ecs = new ExecutorCompletionService<String>(e);
for (Callable<String> s : solvers)
ecs.submit(s);
int n = solvers.size();
for (int i = 0; i < n; ++i) {
String r = ecs.take().get();
if (r != null)
System.out.println("Retrieved: " + r);
}
}
static class PowersOfX implements Callable<String> {
int x;
public PowersOfX(int x) {this.x = x;}
@Override
public String call() throws Exception {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
sb.append(Math.pow(2, i)).append('\t');
System.out.println(Math.pow(x, i));
Thread.sleep(2000);
}
return sb.toString();
}
}
执行此,你会看到数字生成混合(因而执行同时),但单独检索结果不会告诉你这个级别的细节..
你能发布你的代码吗? – akarnokd 2009-06-26 15:28:46
你可以发布一些代码吗? – Javamann 2009-06-26 15:28:47
这些工作是什么?他们可能会阻止连续的事情? – akarnokd 2009-06-26 15:33:34