我想知道以下是否是正确的实现
ExecutorService pool = Executors.newFixedThreadPool(MAX_NSH_THREADS);
Set<Future<Void>> futureRequest = new HashSet<Future<Void>>();
for (String host : SomeCollection)) {
Callable<Void> callable = new FileExtractor(j);
Future<Void> future = pool.submit(callable);
futureRequest.add(future);
}
for (Future<Void> future : futureRequest) {
try {
future.get();
} catch (Exception e) {
logger.error(e);
}
}
pool.shutdown();
根据Javadoc,future.get()
等待每个线程的执行完成,(据我所知)意味着对于未来的每一个,我们将等待单独接收结果。那时的利益来自哪里,或者我做得不对?
答案 0 :(得分:4)
你做对了。
假设SomeCollection
包含100个项目,FileExtractor
需要5秒才能运行,并且您的ExecutorService
线程池包含100个线程。
如果按照上面的方式启动,那么预计代码将运行大约5秒,因为FileExtractor
可能会受I / O限制。 (假设CPU效率最高)。
如果您没有使用Future
,并且所有内容都按顺序运行,则此代码将运行大约500秒。
关键是Future#get()
等待Thread
通过将Callable
提交到ExecutorService
而开始填充结果,而不是等待ExecutorService#submit(Callable)
1}}方法。
答案 1 :(得分:2)
通过致电pool.submit
,您提交后即可开始每个未来。如果您的主线程在此期间还有其他工作要做(在开始期货之间,并等待它们结束),很可能会发生所有期货都在您进入第二个循环时完成,因此实际上会没有阻挡。
如果get
方法确实阻塞了主线程,那么当您等待第一个Future
完成时,请注意其他人仍在并行运行(至少可能,给定足够的处理器时间)