2012-07-24 33 views
1

有一个固定的线程池(让它的大小= 100),我想用于跨应用程序的所有任务。 它用于限制服务器负载。Java:在线程池中共享多个递归任务的工作人员

Task = web crawler,将第一个作业提交给线程池。
该作业可以生成更多作业,依此类推。
一个作业=一个HTTP I/O请求。

问题
假设只有一个执行任务,生成10000个工作。
这些作业现在在线程池队列中排队,并且所有100个线程都用于执行。

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

理念
在我脑海的第一个想法是创建一个自定义的BlockingQueue的,并把它传递给线程池的构造。
该队列将保存几个阻塞队列,每个任务一个。
采取方法将然后选择一个随机队列,并从中取一个项目。
我的问题是,我看不到如何从任务完成后从这个列表中删除一个空队列。这意味着部分或全部员工可能会被取消方法阻止,等待已完成任务的工作。

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

谢谢你!

+0

你可能想检查一下:http://stackoverflow.com/questions/807223/how-do-i-implement-task-prioritization-using-an-executorservice-in-java-5。如果你可以让你的任务实现Comparable,那么这里的解决方案可能会运行良好。 – 2012-07-25 03:45:18

+0

如何使用LIFO优先级队列,即提交的最后一个任务获得最高优先级? – Svilen 2012-07-26 08:57:27

回答

2

我会使用多个队列,并从随机包含的项目队列的画。另外,您可以优先考虑哪个队列应该得到最高优先级

+1

我同意,使用单个池作为顶级请求,另一个用于子请求。您可能只想限制两个池的大小(即第一个池有10个,第二个池有100个) – MadProgrammer 2012-07-24 23:42:15

+0

@MadProgrammer我无法得到为什么我需要2个池:一个用于顶层请求,一个用于子请求。你能否更详细地解释它? – 2012-07-30 19:48:26

+0

@OlegGolovanov两个池的主要原因是,当您排空第二个池并且任何新请求排队等待时,第一个池可以继续处理传入的请求。它还允许分别向两个池提供优先级 – MadProgrammer 2012-07-30 20:41:51

0

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

相关问题