【发布时间】:2021-03-19 21:13:11
【问题描述】:
我为该文件获取了独占的 FileLock,但是当我为该文件创建另一个 RandomAccessFile/FileChannel 并关闭它时,FileLock 被降级,我可以从另一个进程获取该文件的 FileLock。
遵循更好地描述情况的可重复测试
final String path = "/tmp/test.lck";
int sleep = 20_000;
final File dbFile = new File(path);
RandomAccessFile raf = new RandomAccessFile(dbFile, "rw");
final FileLock envLock = raf.getChannel().tryLock(0, 1, false);
System.out.println("Lock acquired " + envLock);
//WE ACQUIRE THE LOCK
//CHECK WITH LSOF you will see
//lsof test.lck
//COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
//java 5088 fefe 4uw REG 253,2 0 8128854 test.lck
//FILE IS PROPERLY LOCKED, YOU CANNOT OBTAIN LOCK FROM ANOTHER PROCESS !!!!
//you can run this same program from another terminal and you will not be able to get the lock , tryLock method will return null
System.out.println("going to sleep " + sleep);
Thread.sleep(sleep);
System.out.println("after sleep " + sleep);
final File dbFile2 = new File(path);
RandomAccessFile raf2 = new RandomAccessFile(dbFile2, "rw");
raf2.close();
System.out.println("channel released and closed");
//AFTER THE CHANNEL IS CLOSED, YOU CAN OBTAIN LOCK FROM ANOTHER PROCESSS !!!! <--- HERE IS THE PROBLEM
//you can run this same program from another terminal and you will be able to get lock
//WE CLOSE THE CHANNEL
//CHECK WITH LSOF you will see
//YOU CHAN SEE THE FD CHANGE FROM uw to u
// COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
// java 5088 fefe 4u REG 253,2 0 8128854 test.lck
System.out.println("going to sleep " + sleep);
Thread.sleep(5 * sleep);
System.out.println("after sleep " + sleep);
问题是,在我为我拥有 FileLock 的同一文件路径创建 RandomAccessFile 后,当我关闭 RandomAccessFile 时,我可以从另一个进程获取文件上的锁。 我认为这是一种奇怪的行为,要么是错误,要么是我遗漏了一些明显的东西。如何正确锁定文件,在随后为同一文件创建 RandomAccessFile 后不会释放锁定(例如 当我想检查我是否持有锁等......)。我已经使用 JDK8 和 JDK11 以及相同的行为对其进行了测试。我的文件系统是 xfs
【问题讨论】: