所以我使用以下内容在文件上创建了一个锁,以便我可以专门编辑它:
File file = new File(filename);
channel = new RandomAccessFile(file, "rw").getChannel();
lock = channel.tryLock();
现在我有第二个线程想要访问同一个文件 - 只是为了阅读,而不是编辑。我怎么做?现在第二个线程将抛出一个 io 异常并通知我文件被锁定。
这是可行的吗?有什么建议么?谢谢
您可以尝试使用 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 中的行为符合预期,但您不一定能确定它们在多个进程中的行为是否符合预期。
通常锁定文件是基于操作系统的,并且当您获取写锁时,它由您获取它的线程独占。但是,您可以做的一件事是在线程之间共享文件对象(但要小心赛车条件)。文件锁定
也许这有帮助!
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()