文件鎖在操作系統(tǒng)中是很平常的事情,當(dāng)多個運(yùn)行的程序需要并發(fā)修改同一個文件時,程序之間需要某種機(jī)制來進(jìn)行通信,使用文件鎖可以有效的阻止多個進(jìn)程并發(fā)修改同一個文件,所以現(xiàn)在的大部分操作系統(tǒng)都提供了文件鎖的功能。
????從JDK1.4的NIO開始,Java開始提供文件鎖的支持。文件鎖控制文件的全部或者部分字節(jié)的訪問。
????在NIO中,Java提供了FileLock來支持文件鎖定功能,在FileChannel中提供了lock()和tryLock()方法來獲得文件鎖FileLock對象,從而鎖定文件。
????lock()和tryLock()方法存在區(qū)別:
- 使用lock()嘗試鎖定某個文件時,如果獲得了文件鎖,該方法就會返回該文件鎖,否則返回null。
- 使用tryLock()嘗試鎖定文件時,它將直接返回而不是阻塞。如果獲得了文件鎖,那么該方法將會返回文件鎖,否則返回null。
????如果FileChannel只是想要鎖定文件的部分內(nèi)容而不是鎖定全部內(nèi)容,則可以像如下的方法一般使用:
- lock(long position,long size,boolean shared)對文件從position開始,長度為size的內(nèi)容加鎖,該方法是阻塞式的。
- tryLock(long position,long size,boolean shared)非阻塞式的加鎖方法。
????當(dāng)shared參數(shù)為true時,表示該鎖是一個共享鎖,允許多個進(jìn)程來讀取該文件,但是阻止其他進(jìn)程獲得對該文件的排它鎖。當(dāng)shared為false時,表示該鎖是一個排它鎖,它將鎖住對該文件的讀寫。程序可以通過調(diào)用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()
)
{
//使用非阻塞方式對指定文件進(jìn)行加鎖
FileLock lock = channel.tryLock();
//程序暫停1秒
Thread.sleep(1000);
//釋放鎖
lock.release();
}catch (Exception ex){
ex.printStackTrace();
}
}
}
????注意:
????文件鎖雖然可以用于控制并發(fā)訪問,但是對于高并發(fā)訪問的情形,還是推薦使用數(shù)據(jù)庫來保存程序信息。
????關(guān)于文件鎖,還要注意的幾點(diǎn)是:
- 在某些平臺上,文件鎖僅僅是建議性的,并不是強(qiáng)制性的。這意味著,即使一個程序不能獲得文件鎖,它也可以對該文件進(jìn)行讀寫。
- 在某些平臺上,不能同步的鎖定一個文件并把它映射到內(nèi)存中。
- 文件鎖是由Java虛擬機(jī)鎖持有的,如果兩個java程序使用同一個Java虛擬機(jī)運(yùn)行,則他們不能對同一個文件進(jìn)行加鎖。
- 在某些平臺上關(guān)閉FileChannel,會釋放Java虛擬機(jī)在該文件上的所有鎖,因此應(yīng)該避免對同一個被鎖定的文件打開多個FileChannel。

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