【问题标题】:How to block until thread pool is empty... with an unknown number of threads?如何阻塞直到线程池为空......具有未知数量的线程?
【发布时间】:2013-09-15 07:47:51
【问题描述】:

假设我有某种线程池。我向它提交了一个线程,它继续前进。我想阻塞主线程,直到池为空/所有线程都完成,最好不要忙着等待。

但是线程可以创建自己的线程并将其添加到池中(事先未知的数量)...所以重要的是,池可以在主线程阻塞时继续正常接受和处理线程。上下文无关紧要:我正在执行图形搜索。

我找到了这么多几乎解决方案:

  • 执行程序可以等待线程完成,但不允许添加新线程。
  • CountDownLatch 非常接近,但在创建新线程时无法递增。

同样有很多关于这个主题的线程,但它们都涉及预先知道正在创建多少线程的程序。实际上,我觉得奇怪的是,这个问题没有被更频繁地(或根本没有)问到!

【问题讨论】:

  • 这个需要是线程还是我们在谈论可以包含在Callable中的工作单元?如果是后者,您应该将工作与并行工作的机制分开。
  • 我的程序搜索图表。每当它到达一个具有多个未访问邻居的顶点时,它会创建一个或多个额外线程以继续向下运行。在死胡同或目标处,线程停止。它从起始顶点的一个线程开始,主线程坐在那里等待搜索完成。这就是线程池或类似结构对我来说有意义的地方。每个新线程都被管理或添加到池中,并且在没有线程运行时完成工作。
  • 我可以使用并发容器或信号量来轻松地忙等待,但是如果主线程完全阻塞直到没有搜索线程正在运行,这对我来说似乎是更有效的解决方案?
  • @Tom 听起来很适合ForkJoinPool
  • @Tom 对于答案来说有点太短了,现在没有时间详细说明。我相信有人会发布更详细的内容(如果不能随意发布您自己的答案)。另请参阅:the tutorial - 虽然它说它已针对 Java 8 进行了更新,但我不确定已经进行了哪些更改(我不会想到很多)。

标签: java multithreading concurrency


【解决方案1】:

正如@Tom 评论的那样,ForkJoinPool 似乎足够了:添加到池中的任务可以在池中产生额外的子任务。要阻止直到所有任务都处理完毕,请使用awaitTermination

请注意,任务和线程不是一回事。您当然可以每个任务有一个线程,但这会效率低下,尤其是在有很多任务的情况下。在内部,池分配给定数量的线程,这些线程将尝试尽快执行挂起的任务。

当一个任务需要产生子任务时,你可以使用

  • invokeAll( listOfTasks ) -- 方法阻塞,直到所有子任务完成。子任务在“父”任务池中执行。
  • getPool().execute( aTask ) -- 您可以在不阻塞井的情况下对子任务进行排队。

第一个选项是使用 ForkJoinPool 的惯用方式。它支持并行分治算法(参见the tutorial 中的示例)。但是,如果任务产生子任务但不关心它们的结果,则第二个选项也应该起作用。

【讨论】:

    猜你喜欢
    • 2012-08-30
    • 1970-01-01
    • 2013-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多