我为该文件获取独占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
1条答案
按热度按时间kxkpmulp1#
我不能在Windows上复制。
来自javadoc的
FileLock
:文件锁代表整个java虚拟机。
此文件锁定api旨在直接Map到底层操作系统的本机锁定功能。因此,文件上的锁应该对所有有权访问该文件的程序可见,而不管这些程序是用什么语言编写的。
在某些系统上,关闭一个通道会释放java虚拟机在底层文件上持有的所有锁,而不管这些锁是通过该通道还是通过在同一文件上打开的另一个通道获得的。强烈建议在程序中使用唯一通道来获取任何给定文件上的所有锁。