我开始学习 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 的方式有效,但我仍然有挥之不去的担忧。
- 我的方法是否高于使用 ExecutorService 的良好编程实践?
- 我应该使用 ExecutorService 的单例实例吗?
- 我不仅应该避免在我的并行方法中进行 I/O 操作,而且还应该避免 JDBC 调用吗?
作为最后一个问题,我试图对 Fork/Join 与 ExecutorService 进行一些研究。我遇到了一篇彻底抨击 Fork/Join API/类的文章。学习 Fork/Join 是否值得?我看到了一些关于 stackoverflow 和其他地方的文章,其中测试用于比较 Fork/Join 与 ExecutorService,并且有图表显示 Fork/Join 与 ExecutorService 更好的 CPU 使用率(通过 Windows 任务管理器)。但是,当我使用 ExecutorService (JDK 1.7.x) 时,我的 CPU 使用率最高。ExecutorService 是否使用最新的 JDK 进行了改进?
任何帮助/指导表示赞赏。