Java的FileLock允许锁定两次

问题描述 投票:0回答:1

在 Ubuntu 上的 Java 中,我使用 FileLock 来锁定文件。该问题经常发生在运行 Debian 的服务器上。为了使其易于重现,我编写了一个最小的示例应用程序(见下文)。正如您所看到的,应用程序首先锁定一个锁定文件,然后一旦成功检索锁定,它就会创建一个测试文件。在释放锁之前,它会再次删除测试文件。由于锁定的原因,永远不应该发生在成功接收锁定后测试文件已经存在的情况。但是,当(同时)运行该应用程序两次时,由于 System.gc() 调用(我需要添加该调用来重现服务器问题),锁似乎被授予了两次。这没有道理。

我使用旧版本的 Java (OpenJDK 11) 和新版本的 Java (OpenJDK 21) 测试了代码。他们提供相同的结果。

参见以下代码:

public static void main(String[] args) throws Exception {
        Random rand = new Random();
        
        while (true) {
            File lockFile = new File("/tmp/lock-file");
            if (!lockFile.exists()) {
                lockFile.createNewFile();
            }
            
            RandomAccessFile rac = new RandomAccessFile(lockFile, "rw");
            FileChannel channel = rac.getChannel();
            FileLock lock = channel.tryLock();

            if (lock == null) {
                System.out.println("Could not get lock");
            } else {
                System.out.println("Got lock");

                File testFile = new File("/tmp/test-file");
                if (testFile.exists()) {
                    throw new Exception("FILE MUST NOT EXIST. LOCK PROBLEM.");
                }
                
                testFile.createNewFile();
                
                // This helped to reproduce the server problem
                System.gc();
                
                Thread.sleep(rand.nextInt(4));
                
                testFile.delete();
                
                if (!lock.isValid()) {
                    throw new Exception("Lock is not valid anymore!");
                }
                
                lock.release();
                channel.close();
                rac.close();
            }
            
            Thread.sleep(rand.nextInt(4));
        }
    }

应用程序第一个实例的输出:

java -jar test.jar
Got lock
Got lock
Got lock

应用程序第二个实例的输出:

java -jar test.jar
Got lock
Got lock
Could not get lock
Got lock
Exception in thread "main" java.lang.Exception: FILE MUST NOT EXIST. LOCK PROBLEM.
    at test.Test.main(Test.java:44)

我尝试在 Java 中使用文件锁定,我预计一个文件不能被两个进程锁定两次。然而,Java 似乎允许两次锁定文件,这对我来说是一个问题。知道出了什么问题吗?

非常感谢!

java locking file-locking
1个回答
0
投票

我自己找到了解决方案。我需要在 if 子句的代码块中添加以下代码

if (lock == null)
:

channel.close();
rac.close();

经过此更改,它可以完美运行。我希望这个答案能为我节省同样的时间!

© www.soinside.com 2019 - 2024. All rights reserved.