我有一个方法,它必须处理数千个文档。
正常处理需要时间,因此我使用 ExecutorService
通过让多个线程并行工作来减少处理时间。
我必须使用这种方法来处理两个长列表。
- 处理
ExecutorService
的方法1:
现在,我已经在方法中初始化了 ExecutorService
并用相同的方法将其关闭。 (被调用两次)
因此它会导致 ExecutorService
创建和关闭两次。
private List<DocDTO> convertData(args) {
ExecutorService service = Executors.newFixedThreadPool(threads);
List<Future<Set<DocDTO>>> futures = new ArrayList<Future<Set<DocDTO>>>();
for (Pro pro : pros.getPros()) {
Callable<Set<DocDTO>> callable = new Callable<Set<DocDTO>>() {
public Set<DocDTO> call() throws Exception {
for loop code
}
};
futures.add(service.submit(callable));
}
service.shutdown();
for (Future<Set<DocDTO>> future : futures) {
if (future.get() != null) {
list.addAll(future.get());
}
}
}
- 处理
ExecutorService
的方法2:
我正在查看以下链接:
http://programtalk.com/java/executorservice-not-shutting-down/
作者在类级别创建了 ExecutorService
。
您能否告诉我在方法级别或类级别创建 ExecutorService
是否是个好主意?
仅供引用,上面代码中的方法一天执行两次
最佳答案
自然的选择是将此类服务设为类字段。
建立这样的服务并不是免费的。您花费了这些开销来“构建”该线程池;以及正确关闭它的时间 - 每次调用该方法时。
大多数时候,这不是您想要的。您希望花费一次该时间(例如:当创建持有服务的对象时)。
唯一的缺点是:现在持有服务的类的“生命周期”很重要。正如您现在可能必须担心对该持有者类所拥有的服务的shutdown()
的显式调用。
换句话说:当您必须担心性能时,您可能会将服务更改为类的字段。
但是:您明确声明该方法每天调用两次。那么您绝对不需要担心创建/关闭该服务所产生的开销。即使开销会导致 1 秒的计算时间 - 每天 2 秒也根本不重要。
因此,鉴于该要求 - 我的(个人)建议:保持代码不变。在出现真正的问题需要修复之前,不要接触正在运行的系统。
关于java - ExecutorService 应该在 bean 的整个生命周期中都处于 Activity 状态,或者应该具有狭窄的(方法)范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44880977/