在Java中,是否有一种方法可以在文件被其他线程锁定时读取该文件?

9

我使用以下方法在文件上创建锁,以便我可以独占地进行编辑:

 File file = new File(filename);
 channel = new RandomAccessFile(file, "rw").getChannel();
 lock = channel.tryLock();

现在我有第二个线程想要访问同一个文件 - 只是读取,不编辑。我该怎么做?现在第二个线程将抛出一个IO异常并通知我文件被锁定。

这可行吗?有什么建议吗?谢谢。

3个回答

4
你可以尝试使用tryLock的三个参数版本来请求共享锁。
这是适当的javadoc文档: http://download.oracle.com/javase/1.4.2/docs/api/java/nio/channels/FileChannel.html#tryLock%28long,%20long,%20boolean%29 基本上,不要再使用"lock=channel.tryLock()",而应该使用"lock = channel.trylock(0, Long.MAX_VALUE, true)"。
另外,你应该小心使用Java中的文件锁定。虽然你可以保证锁在JVM内部按预期工作,但不能保证它们在多个进程之间按预期工作。

1

或许这可以帮助你!

public abstract FileLock tryLock(long position,
                                 long size,
                                 boolean shared)
                         throws IOException

尝试在此通道文件上获取给定区域的锁定。
该方法不会阻塞。调用始终立即返回,无论是已经获得所请求的区域的锁还是未能获得锁。如果由于另一个程序持有重叠锁而无法获取锁,则返回 null。如果由于任何其他原因无法获取锁,则抛出适当的异常。
由位置和大小参数指定的区域不需要包含或甚至重叠实际的基础文件。锁定区域的大小固定;如果锁定区域最初包含文件的末尾并且文件增长超出该区域,则该文件的新部分将不会被锁定。如果预计文件的大小将增长,并且需要对整个文件进行锁定,则应锁定从零开始的区域,该区域不小于文件的预期最大大小。零参数的 tryLock() 方法仅锁定大小为 Long.MAX_VALUE 的区域。
某些操作系统不支持共享锁,在这种情况下,请求共享锁会自动转换为请求独占锁。可以通过调用结果锁对象的 isShared 方法来测试新获取的锁是共享的还是独占的。
文件锁定代表整个 Java 虚拟机。它们不适合控制同一虚拟机内多个线程对文件的访问。
参数: position - 要开始锁定区域的位置;必须是非负的 size - 锁定区域的大小;必须是非负的,并且位置 + 大小之和必须是非负的。 shared - true 请求共享锁,false 请求独占锁 返回值: 表示新获取的锁的锁对象;如果无法获取锁,则返回 null,因为另一个程序持有重叠的锁 抛出: IllegalArgumentException - 如果参数的先决条件不成立 ClosedChannelException - 如果此通道已关闭 OverlappingFileLockException - 如果该 Java 虚拟机已经持有重叠所请求的锁或者如果另一个线程已经在此方法中阻塞并且正在尝试锁定同一文件的重叠区域 IOException - 如果发生其他 I/O 错误 参见: lock(), lock(long,long,boolean), tryLock()

1

通常锁定文件是在操作系统层面进行的,当您获取写锁时,它是由获取锁的线程独占的。然而,您可以做的一件事是在线程之间共享文件对象(但要小心竞争条件)。文件锁定


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接