【问题标题】:How can I make sure that all the spawned threads are done so that processing can continue?如何确保所有生成的线程都已完成,以便继续处理?
【发布时间】:2015-04-20 18:23:16
【问题描述】:

我有一个ConcurrentMap,我将ArrayList 中的元素放到映射中,以供其他线程处理。一旦线程完成其处理,它会将结果添加到ConcurrentMap 中并调用一个方法,以便让我们说“主”线程获取并处理所有结果(来自ConcurrentMapArrayList)。
这种方法有效,但结果是调用该方法的次数与列表中元素的数量一样多。
问题:我可以使用什么构造以便在ConcurrentMap 完全由所有后台线程的结果填充?

【问题讨论】:

  • 你不能在其他线程上调用 join() 吗?
  • @KevinWorkman:线程是由我无法控制的其他构造产生的。基本上它们被封装在其他对象中,我只能为一项任务启动一个。我无权访问/启动任何线程
  • 你知道有多少对象最终会出现在 ConcurrentMap 中吗?你知道什么时候添加了一个项目吗?如果您发布了MCVE,这将更容易谈论 - 处理可以只是对 Thread.sleep() 或其他东西的调用。
  • @KevinWorkman:如果ArrayList 有 N 个元素,则该元素将出现在地图中

标签: java multithreading data-structures concurrency concurrenthashmap


【解决方案1】:

您可以使用 CountDownLatch 将其初始化为 Arraylist 中的总项目,并且每次处理中的项目时使用 countDown 方法将其倒数,

主线程可以在latch上调用await方法,await阻塞线程直到计数器达到零。

【讨论】:

    【解决方案2】:

    在 Java 8 中你可以做到这一点

    ConcurrentMap<Key, Value> map = ...
    listToProcess.parallelStream().forEach(e -> addElementToMap(e, map));
    

    这将使用您拥有的所有 CPU 执行所有元素的处理,并且仅在它们全部完成后返回。

    【讨论】:

    • 啊。抱歉,我使用的是 Java 7,无法升级。谢谢你的sn-p
    • @Jim 在这种情况下,将所有任务添加到 ExecutorService,将所有 Futures 保存在一个列表中,然后等待它们全部完成。
    猜你喜欢
    • 1970-01-01
    • 2018-10-06
    • 2021-02-18
    • 2019-02-14
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-18
    相关资源
    最近更新 更多