有一些类似于这个问题的Java问题,但是没有一个问题能够接受我能找到的答案,而且我的情况更具体一些。我有一个程序,当它们被送入目录时,一次处理一个文件。有时,文件可能会被程序保持锁定状态,以便程序在我的程序可见之后将其关闭几秒钟。我无法控制该程序。在我的程序中,我已经有错误处理,以便在我的程序尝试读取文件时使用该文件。它导致文件被完全跳过。我想要实现的是一个重试方案,以查看文件是否在几秒钟后解锁。在这里的另一个问题中,我发现了使用FileUtils.touch()
的建议。这很方便,因为我已经在我的项目中使用了FileUtils。根据javadoc,FileUtils.touch()
如果该文件正由另一个进程使用,则抛出IOException
。听起来不错。但是,我提到的答案中的一条评论警告说没有任何解释的竞争条件。以下是我考虑实施的代码:
// Implementing Sason's suggestion
int retries = 0;
while (retries < MAX_RETRIES) {
try {
processFile(file);
} catch (IOException ioe) {
// Assumes this is a file in use exception... bad thing?
log.warn("File is in use. Waiting 1 second to retry.");
retries++;
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
log.warn("Thread interrupted while waiting for file lock to clear.");
break;
}
}
}
我意识到文件可能会在FileUtils.touch()和processFile()
方法调用之间再次被锁定(并且我认为这是在我发现的未接受的答案中警告的竞争条件)但是&#39很好。 processFile()
方法将像当前一样处理锁定错误。为了清楚起见,在这种情况下,文件可以被另一个进程打开,但它无法锁定。
此外,虽然有时文件在一两秒后解锁,但在某些情况下,程序从文件中删除会无限期地保持锁定状态。我还需要避免无限尝试重新处理同一个文件,以及在重试耗尽后无法处理文件时能够通知发件人。
我在这里错过了一些东西吗?是否有更好/更安全的方法来做到这一点?
答案 0 :(得分:3)
我会使用SchedueledExecutorService提交一些尝试处理文件的延迟。如果处理失败,请一次又一次地发布工作,直到成功为止。
这里是否需要FileUtils.touch?为什么不尝试读取文件并重试失败?
thread.sleep的东西有点难看。如果处理多个文件,每个文件都必须使用它自己的线程,直到完成为止。 SchedueledExecutorService会更有效率。