• Java NIO中的FileLock(文件锁)


    FileLock,文件锁。

    文件锁在OS中很常见,如果多个程序同时访问、修改同一个文件,很容易因为文件数据不同步而出现问题。给文件加一个锁,同一时间,只能有一个程序修改此文件,或者程序都只能读此文件,这就解决了同步问题,保证了线程安全。

    文件锁是进程级别的,不是线程级别的。文件锁可以解决多个进程并发访问、修改同一个文件的问题,但不能解决多线程并发访问、修改同一文件的问题。

    就是说使用文件锁时,同一进程内(同一个程序中)的多个线程,可以同时访问、修改此文件。

    文件锁是当前程序所属的JVM实例持有的,一旦获取到文件锁(对文件加锁),要调用release(),或者关闭对应的FileChannel对象,或者当前JVM退出,才会释放这个锁。

    一旦某个进程(比如说JVM实例)对某个文件加锁,则在释放这个锁之前,此进程不能再对此文件加锁,就是说JVM实例在同一文件上的文件锁是不重叠的(进程级别不能重复在同一文件上获取锁)。

    文件锁分为2类:

    • 排它锁:又叫独占锁。对文件加排它锁后,该进程可以对此文件进行读写,该进程独占此文件,其他进程不能读写此文件,直到该进程释放文件锁。
    • 共享锁:某个进程对文件加共享锁,其他进程也可以访问此文件,但这些进程都只能读此文件,不能写。线程是安全的。只要还有一个进程持有共享锁,此文件就只能读,不能写。

    使用示例:

     1  //创建FileChannel对象,文件锁只能通过FileChannel对象来使用
     2         FileChannel fileChannel=new FileOutputStream("./1.txt").getChannel();
     3 
     4         //对文件加锁
     5         FileLock lock=fileChannel.lock();
     6 
     7         //对此文件进行一些读写操作。
     8         //.......
     9 
    10         //释放锁
    11         lock.release();

    文件锁要通过FileChannel对象使用。

    有4种获取文件锁的方法:

    • lock()    //对整个文件加锁,默认为排它锁。
    • lock(long position, long size, booean  shared)    //自定义加锁方式。前2个参数指定要加锁的部分(可以只对此文件的部分内容加锁),第三个参数值指定是否是共享锁。
    • tryLock()    //对整个文件加锁,默认为排它锁。
    • tryLock(long position, long size, booean  shared)     //自定义加锁方式。

    如果指定为共享锁,则其它进程可读此文件,所有进程均不能写此文件,如果某进程试图对此文件进行写操作,会抛出异常。

    lock与tryLock的区别:

    • lock是阻塞式的,如果未获取到文件锁,会一直阻塞当前线程,直到获取文件锁
    • tryLock和lock的作用相同,只不过tryLock是非阻塞式的,tryLock是尝试获取文件锁,获取成功就返回锁对象,否则返回null,不会阻塞当前线程。

    FileLock常用的2个方法:

    boolean  isShared()     //此文件锁是否是共享锁

    boolean  isValid()    //此文件锁是否还有效

    在某些OS上,对某个文件加锁后,不能对此文件使用通道映射。

    如何避免死锁:在读写关键数据时加锁,操作完成后解锁;一次性申请所有需要的资源,并且在申请不成功的情况下放弃已申请到的资源。

  • 相关阅读:
    Delphi 获取不重复随机数《LceMeaning》
    轻松一下
    MS SQL字段类型详解《转》
    Go语言优势与劣势
    go语言特点
    初始go语言
    django 短链接改成长连接
    extjs [1]
    Supervisor安装与配置
    InfluxDB命令使用
  • 原文地址:https://www.cnblogs.com/chy18883701161/p/10940390.html
Copyright © 2020-2023  润新知