2014-12-03 115 views
1

我正在編寫消息隊列,但運行緩慢,processFile方法花費太多時間,並且文件長時間滯留在隊列中。如何避免它。消息隊列性能降低

System.out.println("Message Reader Started...."); 
    do 
    { 
     String directoryPath = "C:\\Queue"; 
     int fileCount = new File(directoryPath).list().length; 
     if (fileCount < 1) { 
      System.out.println("Files Not Present"); 
     } 
     else 
     { 
      File[] file = new File(directoryPath).listFiles(); 
      String firstFile = file[0].getAbsolutePath(); 
      processFile(firstFile);    
     }      
    } while (true); 
+0

對於listFiles()沒有保證的順序,你可能正在讀取一個未完全寫入的文件。我建議你閱讀所有的文件(不只是「第一」),只處理那些沒有更新說10或60秒。 – 2014-12-09 18:58:51

+0

不錯的提示謝謝@PeterLawrey – prsutar 2014-12-10 05:42:42

回答

1

您是否嘗試過使用併發性呢?它是併發處理的一個恰當問題。假設文件處理是一種相互排斥作用:

  • 的do while循環的主線程發現閱讀
  • 工藝文件的文件委託給一個執行線程處理
  • 和處理後(我假設讀取文件)內容的處理可以再次並行完成。它像讀取前1000行並委託給一個線程進行處理。

你需要設計一個更好的方式來快速運行。單線程讀取和處理文件列表勢必運行緩慢。

+0

我想到了它,但後來我認爲爲每個文件創建一個新的線程將是凌亂和難以管理。你是否提到任何好的材料來閱讀它。 – prsutar 2014-12-03 16:22:45

+0

閱讀有關執行者服務。這將幫助你。你不需要自己創建線程。 – Nazgul 2014-12-03 16:25:21

0

您的主要問題可能是用於掃描文件夾的CPU使用率。

您應該在循環結束時添加Thread.sleep(100);以使系統有時間呼吸。

您想解決的問題顯然是processFile()方法。你應該按照@Nazgul的評論來實現它,並在它自己的類中使用Runnable接口來實現它。

要限制正在運行的線程數量,請將文件名放在List或Queue中,然後實現一個在List上工作的Thread。您可以添加儘可能多的工作線程,因爲您的系統可以處理。應該同步隊列,以便您可以同時安全地從多個線程中刪除項目。

0

你寫了一個無限循環,那麼爲什麼你擔心單次迭代需要多長時間?

你不需要每次迭代讀取目錄兩次。假設您的processFile刪除了處理的文件(並且可能有另一個線程或進程添加了一些文件,但不刪除),則不需要在每次迭代中讀取目錄。

只讀一次並處理找到的所有文件。如果沒有,則重新讀取目錄。如果還沒有,那麼你可以終止或休息一段時間(或考慮watching目錄,但這有點複雜,可能沒有必要)。

我強烈建議您在開始玩踏板之前改善您的循環(然後使用ExecutorService建議)。