繁体   English   中英

在java中调用ExecutorService.shutDown()

[英]calling ExecutorService.shutDown() in java

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

现在我有一个可调用对象列表,我执行以下操作。

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的方式有效,但我仍然有一些挥之不去的担忧。

  1. 我的方法是使用ExecutorService进行良好的编程实践吗?
  2. 我应该使用ExecutorService的单例实例吗?
  3. 我不仅应该避免并行方法中的I / O操作,还要避免JDBC调用吗?

作为最后一个问题,我试图研究一下Fork / Join vs ExecutorService。 我遇到了一篇完全抨击Fork / Join API /类的文章。 学习Fork / Join值得吗? 我在stackoverflow和其他地方看到了一些文章,其中测试用于比较Fork / Join和ExecutorService,并且有图表显示了Fork / Join vs ExecutorService的更好的CPU使用率(通过Windows任务管理器)。 但是,当我使用ExecutorService(JDK 1.7.x)时,我的CPU使用率是最大值。 使用最新的JDK改进了ExecutorService吗?

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

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

  1. 你是否OuterCallable有顺序依赖? 如果是这样,你的方法很好,但使用ForkJoinPool会更好,因为它会保持较低的工作线程数。 如果没有,最好将一个大的扁平化Callable s集合提交给一个Executor
  2. 仅当您想在几个不同的例程中使用ExecutorService并且希望避免传递它时。 如果它只在someMethod ,那么也可以像你一样在那里实例化它。
  3. 您应该避免需要很长时间才能完成的I / O例程。 如果您的ExecutorService有4个工作线程且所有这些线程都在I / O上阻塞,那么JVM根本不会使用CPU,即使其他Callables可能正在等待进行CPU密集型工作。 只要查询不需要很长时间才能完成,一些JDBC调用就可以了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM