2012-07-24 95 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並使用遞歸任務的「深度」來計算優先級使用單個隊列,當隊列爲空時工作人員被阻塞,在多個隊列周圍不需要隨機化邏輯。