当通过ExecutorCompletionService执行任务时,任务是否并行化?

问题描述:

我提交了5个工作到ExecutorCompletionService,但它好像像工作顺序执行。传递给ExecutorCompletionService的构造函数的ExecutorService是使用newCacheThreadPool表单创建的。我做错了什么?当通过ExecutorCompletionService执行任务时,任务是否并行化?

UPDATE每个工作基本上都在做数据库查询&的一些计算。 ExecutorCompletionService的代码被取消为javadoc。我用自己的Callable实现替换了Callables。

+0

你能发布你的代码吗? – akarnokd 2009-06-26 15:28:46

+0

你可以发布一些代码吗? – Javamann 2009-06-26 15:28:47

+0

这些工作是什么?他们可能会阻止连续的事情? – akarnokd 2009-06-26 15:33:34

ExecutorCompletionService什么都没有与作业执行方式有关,它只是检索结果的简便方法。

Executors.newCachedThreadPool默认执行在单独的线程,这可以并行任务,因为:

  • 任务是独立的,并且不例如在同一个对象内同步;
  • 你有多个硬件CPU线程。

最后一点值得解释。尽管没有任何保证,但实际上Sun JVM支持当前正在执行的线程,因此它永远不会换成另一个线程。这意味着你的5个任务可能由于JVM实现而最终被串行执行,一台多核机器。

执行将取决于许多事情。例如:

  • 的时间长度,以便完成工作
  • 在线程池中的线程(如果认为他们需要一个缓存的线程池只会创建线程)数量

按顺序执行并不一定是错误的。

我假设你的意思是Executors.newCachedThreadPool()。如果是这样,执行应该像你期望的那样并行。

每个工作基本上都在做数据库查询&的一些计算。 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(); 
    } 
} 

执行此,你会看到数字生成混合(因而执行同时),但单独检索结果不会告诉你这个级别的细节..