[英]FileChannel & RandomAccessFile don't seem to work
简而言之:一个使用sqlitejdbc作为后端的swing应用。 当前,启动使用同一数据库文件的多个实例没有问题。 而且应该有。 该文件已锁定(在应用运行时无法将其删除),因此检查应该很简单。 事实并非如此。
File f = new File("/path/to/file/db.sqlite");
FileChannel channel = new RandomAccessFile(f, "rw").getChannel();
System.out.println(channel.isOpen());
System.out.println(channel.tryLock());
结果是
true
sun.nio.ch.FileLockImpl[0:9223372036854775807 exclusive valid]
无论应用程序是否正在运行。 我错过了重点吗? TIA。
FileLock是JVM独有的,而不是单个线程。 因此,如果您在与Swing应用程序相同的进程中运行该代码,则会得到该锁,因为它是由JVM共享的。
如果您的Swing应用程序未在运行,则没有其他进程在争夺该锁,因此您可以很好地获得该锁。
文件系统级别的锁与其他应用程序进行交互。 您可以从FileChannel中获得其中之一。 因此,您在示例代码中执行的操作将使该文件似乎被锁定到另一个进程,例如vi。
但是,JVM中的其他Java线程或进程将看不到该锁。 关键句是“文件锁代表整个Java虚拟机持有。它们不适合控制同一虚拟机中的多个线程对文件的访问。” 您没有看到该锁,因此您正在从与应用程序相同的JVM中运行sqlitejdbc。
因此,问题是如何查看您的JVM是否已经获取了文件锁定(假设您不控制获取该锁定的代码)? 我的一个建议是尝试在文件的另一个子集上获得排他锁,例如使用以下代码:
fc.tryLock(0L, 1L, false)
如果已经有一个锁,则应该获得OverlappingFileLockException。 这有点棘手,但可能有效。
你可以做一点实验吗? 运行该程序的两个副本(只需在睡眠状态下运行代码即可):
public class Main {
public static void main(String [] args) throws Exception {
File f = new File("/path/to/file/db.sqlite");
FileChannel channel = new RandomAccessFile(f, "rw").getChannel();
System.out.println(channel.isOpen());
System.out.println(channel.tryLock());
Thread.sleep(60000);
}
}
如果这不能锁定,则说明tryLock()在OS /驱动器/ JVM上不起作用。 如果这确实锁定了,那么您的逻辑还有其他问题。 在评论中让我们知道结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.