2014-12-03 79 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建议)。