关于SO的其他问题与此非常相似,但没有一个能完全解决我的问题:
我有一个Java程序,我想按计划运行,我不希望一次运行多个副本。所以,我正在使用javax.nio.channels.FileLock
这样(简化):
File fileToLock = new File("lockfile");
RandomAccessFile raf = new RandomAccessFile(fileToLock, "rw");
FileLock lock = raf.getChannel().lock();
// File is locked, do my work
lock.release();
raf.close();
这很好用,除了锁定文件在终止后粘在一起。如果我在程序结束时添加删除:
fileToLock.delete();
在程序终止之前删除文件。大。
除了在同时运行程序的两个副本时,它们都将锁文件作为随机访问文件打开,这意味着它们都指向同一目录条目,并且当持有锁的进程删除时该文件并释放锁,然后第二个进程有一个已锁定的文件,锁定它。
这意味着该程序的另一个实例可以启动,因为请求一个名为“lockfile”的RandomAccessFile
将创建一个 new 文件并将其锁定,即使旧的lockfile仍然存在被另一个进程“锁定”。以下是对事件顺序的快速描述:
lockfile
(inode 123)并锁定它lockfile
(inode 124)并锁定它此时,我有两个进程同时运行,这是我想要避免的。
我也试过File.renameTo
但当然也有同样的问题:文件名一旦被打开就无关紧要了,因为FileChannel
指的是文件描述符,而不是“在文件系统上命名。
我唯一的选择似乎是将锁文件留在原位,即使它没有被主动用作锁文件。这个问题还有其他解决方案吗?