Java Nio Buffer 十一

2018/01/13 Java

Java Nio Buffer 十一

文件锁定

JDK1.4前,Java I/O模型没有文件锁。文件锁可以是共享或者独占的,文件锁定的特性很大程度上依赖于操作系统的实现。不是所有的操作系统和文件系统都是支持共享文件锁的。不支持的操作系统会把共享文件锁自动提升为独占文件锁,可以保证准确性但是会影响性能。

文件锁相关的API 如下:

public abstract class FileChannel
    extends AbstractChannel
    implements ByteChannel, GatheringByteChannel, ScatteringByteChannel
{
    public final FileLock lock( )
    public abstract FileLock lock (long position, long size,boolean shared)
    public final FileLock tryLock( )
    public abstract FileLock tryLock (long position, long size,boolean shared)
}

带参数的lock是在文件内部区域上获得的,要获得一个共享锁,必须先用只读权限打开文件,请求独占锁是需要写权限。参数不能是负数,但是可以超过文件尾,可以提前把要写入数据的区域锁定,如果文件增长超出了锁定区域,没有办法保护锁定区域外的内容。没有参数的函数会锁定能锁定的最大内容。如果锁定范围是有效的,lock方法会阻塞,必须等待前面的所被释放。

tryLock()是锁定方法的非阻塞变体,如果不能立即获取锁,会返回一个null。

获取到的FileLock对象的API如下:

public abstract class FileLock
{
    public final FileChannel channel( )
    public final long position( )
    public final long size( )
    public final boolean isShared( )
    public final boolean overlaps (long position, long size)
    public abstract boolean isValid( );
    public abstract void release( ) throws IOException;
}

FileLock 类封装一个锁定的文件区域。FileLock 对象由 FileChannel 创建并且总是关联到那个特定的通道实例。可以通过调用 channel( )方法来查询一个 lock 对象以判断它是由哪个通道创建的。

一个 FileLock 对象创建之后即有效,直到它的 release( )方法被调用或它所关联的通道被关闭或 Java 虚拟机关闭时才会失效。我们可以通过调用 isValid( )布尔方法来测试一个锁的有效性。一个锁 的有效性可能会随着时间而改变,不过它的其他属性——位置(position)、范围大小(size)和独 占性(exclusivity)——在创建时即被确定,不会随着时间而改变。

可以通过调用 overlaps( )方法来查询一个 FileLock 对象是否与一个指定的文件区域重叠。 不过即使返回值是 false 也不能保证一定能在期望的区域上获得一个锁,因为 Java 虚拟机上的其他地方或者外部进程可能已经在该期望区域上有一个或多个锁了。最好使用 tryLock( ) 方法确认。

尽管一个 FileLock 对象是与某个特定的 FileChannel 实例关联的,它所代表的锁却是与一个底层文件关联的,而不是与通道关联。如果在使用完一个锁后而不释放它的话,可能会导致冲突或者死锁。

Show Disqus Comments

Search

    Table of Contents