2012-12-20 39 views
0

我正在使用Java中的線程編寫應用程序,並且在循環中保持線程的數量不變(新線程與新數據一起傳入)。 我使用ExecutorService來限制線程的數量,但是我在啓動新線程時遇到了問題。循環中的常量線程數Java

我有類似的東西:

ExecutorService execDownload = Executors.newFixedThreadPool(5); 
UniqList<String> documentList = new UniqList<String>("startfile.txt"); 
     Future<UniqList<String>> future; 
     while(!execDownload.isShutdown()) { 
      future = execDownload.submit(new Parser(documentList.get(i))); 
      i++; 
      try { 
       documentList.addAll(future.get()); 
      } catch (InterruptedException | ExecutionException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

Parser是一個可調用對象返回UniqList。我將這個列表中的元素添加到我的全局列表中,該列表是所有文檔名稱的集合。 問題是: 我希望同時運行的解析器數量不變。如果我在程序啓動之前知道文檔的所有名稱,它會很簡單,因爲如果我有100個文件名,我應該調用ExecutorService submit()方法,即100次,但我不知道文檔的所有名稱 - 名稱通過調用此代碼進行解析:

new Parser(documentList.get(i)) 

並且名稱位於文件內部。 所以再多一次的問題 - 如何保持不變的線程數量,當新的數據到達?在上面的代碼中,我只有一個Future Object,它是我認爲的最大的問題 - 我應該創建一系列期貨嗎?但後來如何檢測時,從ExecutorService的某個線程剛回國一些新的數據...

的算法中應該是(我認爲):

  1. 開始與初始參數(第一個文件名)程序
  2. 通過
  3. 列表項
  4. 開始分析器類將它提交給ExecutorService的和提取的起始文件
  5. 所有文件名的文件名添加從#2全局文件名列表
  6. 鉻使用全局文檔名稱列表中的名稱來處理另一個線程和解析文檔。啓動最大線程數(由ExecutorService限制)。解析每一個文件,並提取新的文件名從他們
  7. 添加來自#3名全局文件名列表 回#4

正如你可以看到它像遞歸。我認爲這與解析網站,1個開始節點,第一級分類,第二級分類等相同的問題。

鏈接或示例代碼將非常有用。謝謝。

回答

0

您的代碼幾乎是順序的:future.get()會阻塞,直到任務完成,所以只要前一個任務正在運行,您將無法提交新任務。你既可以:

  • 在一個循環中提交N個任務和存儲期貨再嘗試撥打得到一個,如果未來,並提交一個新的任務
  • 但是這將是重新發明輪子:一個CompletionService似乎做你需要的東西。
+0

我知道,這只是一個樣本 - 這就是爲什麼我問了一些期貨。我會嘗試嘗試CompletionService,謝謝! – swch

0

我建議拋棄的未來,構建解析器瞭解執行人:

execDownload.submit(new Parser(execDownload, documentList.get(i))); 

有無分析器商店這個「execDownload」的ExecutorService作爲一個成員變量。

在Parser.run()的最後,當你有你的新解析文件名列表,你爲他們創造新的解析器,並安排他們,太:

foreach (String newDoc: UniqList) 
{ 
    execDownload.submit(new Parser(execDownload, newDoc)); 
}