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

 

如何避免死鎖:在讀寫關鍵數據時加鎖,操作完成后解鎖;一次性申請所有需要的資源,並且在申請不成功的情況下放棄已申請到的資源。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM