在Java中應用檔案鎖
阿新 • • 發佈:2019-01-23
檔案鎖在作業系統中是很平常的事情,當多個執行的程式需要併發修改同一個檔案時,程式之間需要某種機制來進行通訊,使用檔案鎖可以有效的阻止多個程序併發修改同一個檔案,所以現在的大部分作業系統都提供了檔案鎖的功能。
從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();
}
}
}
注意:
檔案鎖雖然可以用於控制併發訪問,但是對於高併發訪問的情形,還是推薦使用資料庫來儲存程式資訊。
關於檔案鎖,還要注意的幾點是:
- 在某些平臺上,檔案鎖僅僅是建議性的,並不是強制性的。這意味著,即使一個程式不能獲得檔案鎖,它也可以對該檔案進行讀寫。
- 在某些平臺上,不能同步的鎖定一個檔案並把它對映到記憶體中。
- 檔案鎖是由Java虛擬機器鎖持有的,如果兩個java程式使用同一個Java虛擬機器執行,則他們不能對同一個檔案進行加鎖。
- 在某些平臺上關閉FileChannel,會釋放Java虛擬機器在該檔案上的所有鎖,因此應該避免對同一個被鎖定的檔案開啟多個FileChannel。
喜歡的話請掃碼支援一下~~