【问题标题】:In Java cannot identify out when multiple producer/consumer has completed在 Java 中无法识别多个生产者/消费者何时完成
【发布时间】:2011-11-14 17:21:00
【问题描述】:

有一个多生产者消费者模式生产者1->消费者1/生产者2->消费者2/生产者3,每个生产者都使用一个完成服务,但我在编写完成后的逻辑编码时遇到问题。

问题是 main 将一些 (x) 任务放在生产者 1 队列中,这反过来又会导致生产者 1 将 (y) 任务放在生产者 2 上,并且生产者 2 将 z 任务放在生产者 3 上。x, y和 z 不同,因此 main 不能只查看生产者 3 完成队列并获取 z 期货,因为 main 不知道 z。

所以我尝试了毒丸的想法和初始化为 3 的 CountDownLatch,主要知道生产者 1 只有 x 个任务,所以我可以在最后提交毒丸,然后当生产者 1 收到它时,它可以减少锁存器和向生产者 2 发送毒丸,生产者 2 收到一个它会减少锁存发送给生产者 3 的锁存器。当生产者 3 收到它时,它会减少锁存器。 main 只是做 countdownlatch.await() 并且在所有任务完成之前无法继续。但这只有在每个 executor 服务仅限于一个线程时才有效,因为当生产者收到毒丸时,它仅意味着所有前面的任务都已启动并没有完成。

那么我该如何解决这个问题,我想我一定是在某个地方错过了一个更简单的解决方案。

【问题讨论】:

  • 你能给我们一些你的类型形式的代码吗?每个生产者都生成相同的输出类型吗?
  • @user294896:我经常使用“毒丸”,但我不确定我是否理解您所说的 “..因为当生产者收到毒丸时,它仅表示所有前面的任务都已开始......” 消费者应该收到毒丸(而不是生产者)然后采取相应的行动:例如通过减少闩锁和/或创建新的生产者(如果我正确理解了你的例子)。但无论如何:当你服用一颗药丸时,你应该决定你要做什么。仅仅制造一颗毒丸应该没有任何效果。你能澄清一下吗?
  • @user29489 当我说“由生产者接收”时,因为该类是生产者和消费者。所以该类接收工作,并在完成时将新工作传递给不同类型的生产者/消费者。
  • @user294896:所以,如果我理解正确,您是在为所有不同的 “生产者和消费者” [i] 类减少一个唯一的锁存器?如果是这样,如果您有多个线程,显然它不会起作用:您至少需要 3 个药丸每个线程要并行运行。但无论如何,我不确定我是否理解你想要做什么:你是否希望你所有的,比如说,平行的 "consumer2/producer3" 同时开始他们的工作(即当所有 "consumer1 /producer2" 已完成消费)?问题是:您不必总是使用同一种药丸:可以有生产药丸、消费药丸等。
  • @user294896 你说的太复杂了,但没关系,因为我有一个正确的答案,谢谢。

标签: java producer-consumer executorservice completion-service


【解决方案1】:

您可以依次关闭和等待每个executorService的终止。

ExecutorService[] services = { executor1, executor2, executor3 };
for(ExecutorService service: services) {
    service.shutdown();
    service.awaitTermination(1, TimeUnit.MINUTES);
}

【讨论】:

  • 因此,一旦将任务提交给生产者 1,它就会关闭,awaitTermination() 将在生产者 1 完成之前不会返回,此时对生产者 2 执行 shutdown() 是安全的,因为它会收到所有任务,我不需要毒丸或闩锁,甚至不需要完成服务,非常感谢我现在就试试。
  • 是的,我应该包括一个解释。 Shutdown 会阻止新任务,并在所有任务完成后终止服务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-14
  • 2019-05-24
  • 1970-01-01
相关资源
最近更新 更多