1. 程式人生 > >在Java中應用檔案鎖

在Java中應用檔案鎖

檔案鎖在作業系統中是很平常的事情,當多個執行的程式需要併發修改同一個檔案時,程式之間需要某種機制來進行通訊,使用檔案鎖可以有效的阻止多個程序併發修改同一個檔案,所以現在的大部分作業系統都提供了檔案鎖的功能。

    從JDK1.4的NIO開始,Java開始提供檔案鎖的支援。檔案鎖控制檔案的全部或者部分位元組的訪問。

    在NIO中,Java提供了FileLock來支援檔案鎖定功能,在FileChannel中提供了lock()和tryLock()方法來獲得檔案鎖FileLock物件,從而鎖定檔案。

    lock()和tryLock()方法存在區別:

  • 使用lock()嘗試鎖定某個檔案時,如果獲得了檔案鎖,該方法就會返回該檔案鎖,否則返回null。
  • 使用tryLock()嘗試鎖定檔案時,它將直接返回而不是阻塞。如果獲得了檔案鎖,那麼該方法將會返回檔案鎖,否則返回null。

    如果FileChannel只是想要鎖定檔案的部分內容而不是鎖定全部內容,則可以像如下的方法一般使用:

  • lock(long position,long size,boolean shared)對檔案從position開始,長度為size的內容加鎖,該方法是阻塞式的。
  • tryLock(long position,long size,boolean shared)非阻塞式的加鎖方法。

    當shared引數為true時,表示該鎖是一個共享鎖,允許多個程序來讀取該檔案,但是阻止其他程序獲得對該檔案的排它鎖。當shared為false時,表示該鎖是一個排它鎖,它將鎖住對該檔案的讀寫。程式可以通過呼叫FileLock的isShared來判斷它獲得的鎖是否為共享鎖。

    處理完檔案之後通過FileLock的release()方法釋放檔案鎖。

    考慮下面這個示例:

import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

public class FileLockTest {
    public static void main(String[] args){
        try(
                //使用FileOutputStream獲取FileChannel
                FileChannel channel =
new FileOutputStream("a.txt").getChannel() ) { //使用非阻塞方式對指定檔案進行加鎖 FileLock lock = channel.tryLock(); //程式暫停1秒 Thread.sleep(1000); //釋放鎖 lock.release(); }catch (Exception ex){ ex.printStackTrace(); } } }

    注意:

    檔案鎖雖然可以用於控制併發訪問,但是對於高併發訪問的情形,還是推薦使用資料庫來儲存程式資訊。

    關於檔案鎖,還要注意的幾點是:

  1. 在某些平臺上,檔案鎖僅僅是建議性的,並不是強制性的。這意味著,即使一個程式不能獲得檔案鎖,它也可以對該檔案進行讀寫。
  2. 在某些平臺上,不能同步的鎖定一個檔案並把它對映到記憶體中。
  3. 檔案鎖是由Java虛擬機器鎖持有的,如果兩個java程式使用同一個Java虛擬機器執行,則他們不能對同一個檔案進行加鎖。
  4. 在某些平臺上關閉FileChannel,會釋放Java虛擬機器在該檔案上的所有鎖,因此應該避免對同一個被鎖定的檔案開啟多個FileChannel。

喜歡的話請掃碼支援一下~~