通过期货实施线程

时间:2012-01-17 21:44:28

标签: java multithreading future

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

    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()等待每个线程的执行完成,(据我所知)意味着对于未来的每一个,我们将等待单独接收结果。那时的利益来自哪里,或者我做得不对?

2 个答案:

答案 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完成时,请注意其他人仍在并行运行(至少可能,给定足够的处理器时间)