Java 如果文件没有';不使用锁定就不能从并发运行的进程中存在吗?

Java 如果文件没有';不使用锁定就不能从并发运行的进程中存在吗?,java,concurrency,parallel-processing,locking,nio,Java,Concurrency,Parallel Processing,Locking,Nio,假设两个(或更多)并发运行的Java进程需要检查文件是否存在,如果文件不存在则创建它,然后在运行过程中可能从该文件中读取。我们希望防止多个写入进程相互碰撞和/或读取进程读取不完整或不一致的文件版本 我们目前正在做的是使用JavaNIO文件锁来仲裁这种情况。一个进程设法在要使用FileChannel.tryLock()创建的文件上获取独占锁并创建它,而其他并发运行的进程无法获取锁并退回到使用内存中版本的文件进行运行 然而,锁定给我们的计算场带来了各种各样的问题,所以我们正在探索替代方案。所以我要问

假设两个(或更多)并发运行的Java进程需要检查文件是否存在,如果文件不存在则创建它,然后在运行过程中可能从该文件中读取。我们希望防止多个写入进程相互碰撞和/或读取进程读取不完整或不一致的文件版本

我们目前正在做的是使用JavaNIO文件锁来仲裁这种情况。一个进程设法在要使用
FileChannel.tryLock()
创建的文件上获取独占锁并创建它,而其他并发运行的进程无法获取锁并退回到使用内存中版本的文件进行运行

然而,锁定给我们的计算场带来了各种各样的问题,所以我们正在探索替代方案。所以我要问你的问题是:有没有一种方法可以在不使用文件锁的情况下安全地执行此操作?

例如,当进程发现一个文件不存在时,是否可以写入独立的临时文件,然后在写入临时文件后或多或少地“原子地”移动临时文件?在这个场景中,我们可能会得到多个writer进程,但是如果从文件中读取的任何进程总是读取一个或另一个版本,而不是两个或多个版本的混合,那么这就没问题了。但是,我不认为所有的操作系统都能保证,如果您打开了一个文件进行读取,那么即使文件在读取过程中被覆盖,您也会继续从文件的原始版本进行读取

任何建议都将不胜感激

假设两个(或更多)并发运行的Java进程需要检查文件是否存在,如果文件不存在则创建它,然后在运行过程中可能从该文件中读取

我不太明白问题的“创建和阅读”部分。如果您希望确保您有一个唯一的文件,那么您可以使用并检查以确保它返回
true
。引用Javadocs:

在以下情况下,以原子方式创建一个以此抽象路径名命名的新空文件 并且仅当具有此名称的文件尚不存在时。支票 文件的存在以及文件的创建(如果不存在) 是一个相对于所有其他操作都是原子的单一操作 可能影响文件的文件系统活动

这将为您提供一个只有该进程(或线程)才能“拥有”的唯一文件。但是,我不确定您打算如何让编写器知道要写入哪个文件

如果您正在谈论创建一个独特的文件,您可以编写它,然后将其移动到一个写入目录中以供使用,那么上述操作应该会起作用。完成后,还需要在write目录中创建一个唯一的名称

您可以使用以下内容:

private File getUniqueFile(File dir, String prefix) {
    long suffix = System.currentTimeMillis();
    while (true) {
        File file = new File(dir, prefix + suffix);
        // try creating this file, if true then it is unique
        if (file.createNewFile()) {
           return file;
        }
        // someone already has that suffix so ++ and try again
        suffix++;
    }
}

或者,您也可以使用
UUID.randomUUID()
或其他方法创建一个唯一的文件名来生成一个唯一的名称。

多个进程通常在不同的机器上运行,并通过NFS或类似方式访问文件。你认为File.createNewFile()的原子性保证在这种情况下仍然适用吗?不知道@David。我在你的问题中没有看到任何关于NFS的内容。我认为您必须了解NFS如何处理
FileSystem.createFileExclusive(…)
调用。