在java中调用ExecutorService.shutDown()

我开始学习ExecutorService类。 文档(和在线教程)表示始终调用ExecutorService.shutDown()来回收资源。 但是,该文档还称,在您调用shutDown()之后,不会接受任何新任务。 所以,我的问题是,当我需要并行化数据处理时,是否总是必须实例化一个新的ExecutorService?

现在我有一个Callable对象列表,我做了以下操作。

public void someMethod() {
 List<OuterCallable> outerCallables = getOuterCallables();
 ExecutorService executor = Executor.newFixedThreadPool(NUM_CPUS);
 executor.invokeAll(tasks);
 executor.shutDown();
}

然而,我的OuterCallable也使用InnerCallable分割数据或并行执行数据处理。

public class OuterCallable implements Callable<Long> {
 public Long call() throws Exception {
  long result = 0L;

  List<InnerCallable> innerCallables = getInnerCallables();
  ExecutorServices executor = Executor.newFixedThreadPool(NUM_CPUS);
  executor.invokeAll(tasks);
  executor.shutDown();

  return result;
 }
}    

我不记得它是用于ExecutorService还是Fork / Join方法,但我记得文档和教程指出操作数据的实际并行过程不应涉及I / O操作,所有内容都应在内存中完成。 然而,在我的InnerCallable中,我实际上是在进行JDBC调用(这里没有显示)。

最终,我使用ExecutorService的方式起作用,但我仍然有一些疑虑。

  • 是我使用ExecutorService的良好编程习惯的方法吗?
  • 我应该使用ExecutorService的单例实例吗?
  • 我应该不仅避免我的并行方法中的I / O操作,还要避免JDBC调用?
  • 作为最后一个问题,我试图在Fork / Join和ExecutorService上进行一些研究。 我遇到了一篇完全抨击Fork / Join API /类的文章。 学习Fork / Join是否值得? 我在stackoverflow和其他地方看到了一些文章,其中使用了测试来比较Fork / Join和ExecutorService,并且有些图显示Fork / Join vs ExecutorService(通过Windows任务管理器)的更好CPU使用率。 然而,当我使用ExecutorService(JDK 1.7.x)时,我的CPU使用率是最大的。 有最新的JDK改进了ExecutorService吗?

    任何帮助/指导表示赞赏。


    您应该添加awaitTermination调用,因为shutDown无需等待Callables完成即可返回。 除此之外,

  • 你的OuterCallable是否具有顺序依赖性? 如果是这样,你的方法是好的,但使用ForkJoinPool将是可取的,因为它会保持低工作线程的数量。 如果不是的话,最好将一个扁平化的Callable s集合提交给一个Executor
  • 只有当你想在几个不同的例程中使用ExecutorService并且想避免传递它时。 如果它只用于someMethod ,那么可以像在做那样在那里实例化它。
  • 您应该避免需要很长时间才能完成的I / O例程。 如果您的ExecutorService有4个工作线程,并且所有这些线程都在I / O上阻塞,那么JVM将根本不使用CPU,即使其他可加载项可能正在等待CPU密集型工作。 只要查询不需要很长时间就可以完成,几个JDBC调用就可以了。
  • 链接地址: http://www.djcxy.com/p/57779.html

    上一篇: calling ExecutorService.shutDown() in java

    下一篇: No compliant way to convert signed/unsigned of same size