目录轮询的最佳实践

我必须进行批处理以自动化业务流程。 我必须定期轮询目录以检测新文件并进行处理。 在处理旧文件时,可以使用新文件。目前,我使用quartz调度程序和线程同步来确保只有一个线程可以处理文件。

部分代码是:

应用程序的context.xml




DocumentProcessor
…..

 public void processDocuments() { LOG.info(Thread.currentThread().getName() + " attempt to run."); if (!processing) { synchronized (this) { try { processing = true; LOG.info(Thread.currentThread().getName() + " is processing"); List xmlDocuments = documentManager.getFileNamesFromFolder(incomingFolderPath); // loop over the files and processed unlock files. for (String xmlDocument : xmlDocuments) { processDocument(xmlDocument); } } finally { processing = false; } } } } 

对于当前代码,我必须阻止其他线程在处理一个线程时处理文件。 这是一个好主意吗 ? 或者我们支持multithreading处理。 在这种情况下,我如何知道哪些文件正在处理以及哪些文件刚刚到达? 任何想法都非常感激。

我会用这些部分构建它:

  1. 城堡与TxF的交易
  2. FileSystemWatcher JavaVersion
  3. TransactionScope(没有java版本,除非你经常破解它)
  4. 一个无锁队列 *(论文讨论perf Java vs .Net,可能能从Java获取源代码 ) 基于Java锁的队列

    这样:

当有一个新文件时,文件系统观察者会检测到它(记得放置正确的标志,处理错误条件并设置Enbled < - True并注意双打),将文件路径放入队列中。

你有一个应用程序线程,n个工作线程。 如果这是唯一的应用程序,他们会在队列上旋转等待TryDequeue,否则它们会在监视器上阻塞(!Monitor.Enter(has_items));

当一个工作线程通过de-queue操作获得一个路径时,它开始处理它,现在没有其他线程可以对它起作用。 如果有两倍的输出(取决于您的设置),则可以在编写输出文件时使用文件事务。 如果Commit操作失败,那么您知道另一个线程已经写入了输出文件,并继续轮询队列。

  • 竞争条件,请参阅: http : //groups.google.com/group/lock-free/browse_thread/thread/c3b83466b27f6372

我会做以下事情:

  • 一个获取文件名并将其添加到同步队列的线程。

  • 多个线程来执行实际读取:从同步队列中获取一个项目并对其进行处理。

要检查文件是否被使用,您只需尝试重命名/移动它。