【发布时间】:2015-08-13 18:36:21
【问题描述】:
我想测试一下是否可以锁定文件X。如果文件不存在或无法锁定,则失败。这听起来很简单,但我总是陷入死胡同。答案的捷径是提供一种获取 FileChannel 的方法,我可以对其进行独占锁定,而不会产生任何创建文件的风险。让我解释一下……
如果没有可写的 FileChannel,我就无法使用 NIO lock(),如果不打开文件 X,我就无法获得可写的 FileChannel,如果它不存在,就会创建它。我发现的每个尝试以可写方式打开文件 X 的 Java 方法都会创建它,如果它不存在并且似乎没有办法将文件独占锁定在只读 FileChannel 上。
即使首先检查以确认文件是否存在也是有问题的。这是我最新的代码:
private LockStatus openAndLockFile(File file) {
if (Files.notExists(file.toPath())) {
synchronized (fileList) {
removeFile(file);
}
return LockStatus.FILE_NOT_FOUND;
}
try {
rwFile = new RandomAccessFile(file, "rw");
fileLock = rwFile.getChannel().lock();
}
catch ...
此代码的问题在于,当NotExists 代码运行时该文件可能存在,但在new RandomAccessFile(file, "rw") 运行时已消失。这是因为我在多个线程和多个进程中运行此代码,这意味着代码必须是气密且坚如磐石的。
这是我现有代码在两个进程中运行的问题示例:
1:进程A检测到新文件
2:进程B检测到同一个文件
3:进程A处理文件并将其移动到另一个文件夹
问题 ---> 进程 B 不小心创建了一个空文件。哎呀!!!
4:进程 B 检测到进程 B 创建的新文件并对其进行处理,创建一个 0 字节的重复文件。
5:进程A也检测到进程B意外创建的新文件,并尝试对其进行处理……
这是一个使用 C# 的示例,说明我正在尝试做的事情:
Stream iStream = File.Open("c:\\software\\code.txt", FileMode.Open,
FileAccess.Read, FileShare.None)
非常感谢任何帮助或提示!谢谢!
【问题讨论】:
-
围绕关键块同步
-
感谢您的建议。当这段代码在完全独立的进程中运行时,它是如何工作的?可能在不同的机器上?
-
那么显然使用文件是错误的方法,除非文件系统在这些机器之间共享。这可能会更好:stackoverflow.com/questions/1059580/distributed-lock-service
-
感谢您的建议,但我没有使用文件来制作分布式锁系统。我正在处理这些文件。文件锁是为了确保在任何时间点只有一个线程在处理任何给定的文件。
-
我正在查看完全相同的问题。你找到解决办法了吗?谢谢
标签: java multithreading locking filechannel