【问题标题】:Collecting Return Values from Launched Threads? [latest Java]从启动的线程中收集返回值? [最新Java]
【发布时间】:2009-12-04 07:20:23
【问题描述】:

我正在寻找最简单、最直接的方法来实现以下内容:

  • main 启动并启动 3 个线程
  • 所有 3 个任务都处理并以结果值结束(我需要以某种方式返回?)
  • main 在每个线程上等待 (.join?) 以确保它们已全部完成 3 个任务
  • main 以某种方式从每个线程获取值(3 个值)

那么剩下的就比较简单了,处理3个结果然后终止……

现在,我一直在做一些阅读并发现了多种想法,例如:

  • 使用 Future,但这是为了异步,当主线程需要阻塞等待所有 3 个衍生线程完成时,这真的是个好主意吗?
  • 传入一个对象(给一个线程),然后简单地让线程用结果“填充”它
  • 不知何故使用 Runnable(尚不确定)。

无论如何 - 最好、最简单的推荐方法是什么? 谢谢,

【问题讨论】:

    标签: java multithreading


    【解决方案1】:
    List<Callable<Result>> list = ... create list of callables
    
    ExecutorService es = Executors.newFixedThreadPool(3);
    List<Future<Result>> results = es.invokeAll(list);
    

    ExecutorService.invokeAll 方法只会在所有任务(Callable 的实例)正常完成或抛出异常后返回。

    详见ExecutorService(主要是它的invokeAll方法)、ExecutorsCallable

    【讨论】:

    • 我建议使用 newCachedThreadPool 或 newFixedThreadPool(list.size()) 以防任务数量发生变化。有人可以在没有意识到数字 3 的重要性的情况下更改任务数量,当然这一切都会奏效,但效率不如预期。
    • 是的,我完全同意。起初我在示例中也使用了 newCachedThreadPool(),但后来将其更改为使用具有 3 个线程的固定线程池,这正是 Shaitan00 所要求的。
    【解决方案2】:

    您也可以使用来自 java.util.concurrent 的信号量。

    创建一个具有 1 - #threads 许可的新信号量,并在信号量上进行主调用 acquire()。

    当你创建的每个线程都完成了它的工作后,让它调用 release() 方法。

    由于您创建了一个带有负数许可的信号量,因此对 acquire() 的调用将阻塞,直到该数字变为正数。在您的所有线程都在 Semaphore 上释放许可之前,这不会发生。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-19
      • 1970-01-01
      • 2013-03-01
      • 2013-11-06
      • 2012-02-27
      相关资源
      最近更新 更多