【问题标题】:Java: sharing workers in thread pool for several recursive tasksJava:在线程池中为多个递归任务共享工作者
【发布时间】:2012-07-24 22:30:04
【问题描述】:

有一个固定线程池(大小为 100),我想将其用于我的应用程序中的所有任务。 用于限制服务器负载。

Task = 网络爬虫,将第一个作业提交到线程池。
该工作可以产生更多工作,等等。
一项作业 = 一项 HTTP I/O 请求。

问题
假设只有一个正在执行的任务,它产生了 10000 个作业。
这些作业现在在线程池队列中排队,所有 100 个线程都用于执行它们。

假设我现在提交第二个任务。
第二个任务的第一个作业是队列中的第 10001 个。
它只会在第一个任务排队的 10000 个作业之后执行。
所以,这是一个问题 - 我不希望第二个任务等待这么长时间才能开始它的第一个工作。

想法
我想到的第一个想法是创建一个自定义 BlockingQueue 并将其传递给线程池构造函数。
该队列将包含多个阻塞队列,每个任务一个
然后,它的 take 方法会选择一个随机队列并从中取出一个项目。
我的问题是,当它的任务完成时,我看不到如何从这个列表中删除一个空队列。这意味着部分或所有工作人员可能会在 take 方法上被阻塞,等待来自已完成任务的作业。

这是解决此问题的最佳方法吗?
我无法在书籍或互联网上找到它的任何模式:(

谢谢!

【问题讨论】:

  • 你可能想看看这个:stackoverflow.com/questions/807223/…。如果你能让你的任务实现 Comparable,那么这里的解决方案可能会很好。
  • 如何使用LIFO优先队列,即最后提交的任务获得最高优先级?

标签: java recursion executorservice


【解决方案1】:

我会使用多个队列并从包含项目的随机队列中抽取。或者,您可以优先考虑哪个队列应该获得最高优先级。

【讨论】:

  • 我同意,对顶级请求使用单个池,对子请求使用另一个池。您可能只想限制两个池的大小(即第一个池有 10 个,第二个池有 100 个)
  • @MadProgrammer 我不明白为什么我需要 2 个池:一个用于顶级请求,一个用于子请求。你能详细解释一下吗?
  • @OlegGolovanov 使用两个池的主要原因是,当您排空第二个池并且任何新请求排队等待时,第一个池可以继续处理传入请求。它还允许分别为两个池提供优先级
【解决方案2】:

我建议使用单个PriorityBlockingQueue 并使用递归任务的“深度”来计算优先级。使用单个队列时,当队列为空并且不需要围绕多个队列进行随机化逻辑时,工作人员会被阻塞。

【讨论】:

    猜你喜欢
    • 2017-01-06
    • 1970-01-01
    • 1970-01-01
    • 2015-05-07
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    • 2013-01-18
    • 2013-06-05
    相关资源
    最近更新 更多