【问题标题】:Recursion-aware ThreadPool in Java?Java中的递归感知线程池?
【发布时间】:2016-01-26 19:38:01
【问题描述】:

我一直在寻找“递归感知”的 java 线程池。也就是说,如果我创建一个固定大小为 N 的固定线程池,然后提交 N 个任务,一切都好,只要这些任务没有,反过来,向线程池提交额外的任务,然后等待结果。一旦发生这种情况,使用 Executors.newFixedThreadPool(int nThreads) 创建的我的 ThreadPool 就会挂起并且永远不会完成,因为我的 ThreadPool 已经饱和并且没有等待任务无法分配执行,因为池中的所有线程都在忙于等待它们完成。

我意识到这听起来很偏执,但我有一个案例,我有一个计算密集型应用程序,在某一时刻,我有 16,000 个可以并行执行的任务。线程之间没有通信或同步——我只需要等待它们完成执行。问题是,这 16,000 个任务中的每一个都可以分解成 X 个任务,这些任务可以再次并行执行,彼此之间不需要通信或同步。

危险/担忧是有人会决定尝试并行化这第二级步骤,这将非常合理地阻塞我的线程池。

是否有任何库可以创建和管理 ThreadPool 来识别我已经在属于线程池的线程中执行,然后自动安排任务在当前线程中执行,而不是等待待提交到 ThreadPool 的任务(但仅限于 ThreadPool 已经饱和且有待执行任务积压的情况?

我已经实现了一个非常粗略的演示/概念验证,但如果有标准的、经过测试的、可接受的实现可用,那会更开心。

【问题讨论】:

    标签: java multithreading recursion concurrency


    【解决方案1】:

    这个问题听起来是为 Java 7 中引入的 Fork/Join pattern 量身定做的。

    fork/join 框架是 ExecutorService 接口的实现,可帮助您利用多个处理器。它专为可以递归分解成小块的工作而设计

    【讨论】:

    • 遗憾的是,我暂时被 Java 6 困住了。
    • @NathanKummer 对于你想要做的事情,你真的应该使用 Java 8,它具有使用 Fork/Join 的 parallelStream() 并且几乎可以肯定是适合这项工作的工具。
    • 这正是我想要的。感谢您的帮助!
    【解决方案2】:

    如果您使用的是 Java 8,则可以使用来自 ExecutorsworkSteaingPool,它返回 ForkJoinPool

    static ExecutorService  newWorkStealingPool()
    

    使用所有可用处理器作为目标并行级别创建一个工作窃取线程池。

    使用这个API的好处:直到java 7,如果你使用ForkJoinPool,你必须将任务分成RecursiveActionRecursiveTask。但是在 Java 8 中,您可以使用 newWorkStealingPool() 作为 ExecutorService 本身,它隐藏了所有的复杂性。

    这个工厂方法是 Java 8 的一部分,它返回一个 ForkJoinPool 类型的执行器,它的工作方式与普通执行器略有不同。 ForkJoinPools 不是使用固定大小的线程池,而是为给定的并行大小创建的,默认情况下是主机 CPU 的可用内核数。

    看看这个article的用法。

    【讨论】:

      猜你喜欢
      • 2011-02-06
      • 2014-12-21
      • 2017-01-06
      • 2011-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-19
      • 1970-01-01
      相关资源
      最近更新 更多