欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java NIO中的FileLock(文件锁)

程序员文章站 2022-03-20 08:50:45
FileLock,文件锁。 文件锁在OS中很常见,如果多个程序同时访问、修改同一个文件,很容易因为文件数据不同步而出现问题。给文件加一个锁,同一时间,只能有一个程序修改此文件,或者程序都只能读此文件,这就解决了同步问题,保证了线程安全。 文件锁是进程级别的,不是线程级别的。文件锁可以解决多个进程并发 ......

 

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上,对某个文件加锁后,不能对此文件使用通道映射。

 

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