2

我想知道以下是否是正确的实现

    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()等待每个线程的执行完成,这(据我了解)意味着对于未来的每一个,我们将分别等待接收结果。那时的好处来自哪里,或者我做得不对?

4

2 回答 2

4

你做得对。

假设它SomeCollection包含 100 个项目,FileExtractor运行需要 5 秒,并且您的ExecutorService线程池包含 100 个线程。

如果按照上面实现的方式启动,预计代码将运行大约 5 秒,因为FileExtractor可能会受到 I/O 限制。(假设最大 CPU 效率)。

如果你不使用Future's,并且一切都是连续运行的,那么这段代码将运行大约 500 秒。

关键是Future#get()等待结果由Threadstart 通过提交你Callable来填充ExecutorService,而不是在ExecutorService#submit(Callable)方法处等待。

于 2012-01-17T21:59:23.887 回答
2

每个未来都会在您提交后立即启动,方法是调用pool.submit. 如果您的主线程在此期间还有其他工作要做(在开始期货和等待它们结束之间),很容易发生所有期货在您进入第二个循环时已经完成,所以实际上会有不可阻挡。

如果该get方法确实阻塞了主线程,而您正在等待第一个Future完成,请注意其他人仍在并行运行(至少可能,给定足够的处理器时间)。

于 2012-01-17T22:01:07.497 回答