1.文件鎖的分類文件鎖分為阻塞式文件鎖和非阻塞式的文件鎖,可以通過new FileChannel().tryLock /lock,后者是阻塞式,阻塞式意思是指當前進程沒有獲得文件鎖即刻等待直到有進程將對應文件的鎖釋放。
2.文件鎖針對進程這里指進程的原因是因為對文件鎖而言一個線程同一時間段對同一個文件只能加上一把鎖,只有等待當前線程釋放掉后,才能繼續對文件加鎖,不然會報OverlappingFileLockException的錯誤,所以文件鎖是進程間的鎖。
3.線程間預防重復加鎖,減少讀寫文件等待時間//給該文件加鎖
RandomAccessFile fis = new RandomAccessFile(file, "rws"); //單一線程的讀寫同步
FileChannel fcin=fis.getChannel(); // 獲得文件通道
FileLock flin=null; //聲明文件鎖對象
int operateNum=10; //若文件鎖一直別占用,設置最大讀取次數為10次,超出次數表示文 //件不可讀,
For(int i=0;i<operateNum,i++){
try {
flin = fcin.tryLock(); // 獲取文件非阻塞鎖,如果不能獲取,繼續等待0.5s.
break;
} catch (Exception e) {
System.out.println("有其他線程正在操作該文件,當前線程休眠500毫秒");
sleep(500);
If((i+1)>=operateNum){
Throw e //文件被強制占用 ,處于不可讀的狀態
}
}
}
//獲取成功
//進行文件的讀或寫的操作
RandomAccessFile 流中讀出文件的數據;
RandomAccessFile 流向該文件寫入新數據;
//該文件的操作完畢,釋放該文件鎖和相關資源
flin.release();
fcout.close();
out.close();
4.線程寫文件加鎖后,讀文件線程不需加鎖的方法(保證讀寫同步) 寫線程:
RandomAccessFile fos=new RandomAccessFile(file,"rws");
FileChannel fileC=fos.getChannel();
FileLock fileL=null;
while(true){
try{
fileL=fileC.lock();
break;
}catch(Exception e){
try {
System.out.println("**********************************文件被操作,寫文件線程休眠0.2m");
Thread.sleep(200);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
/*注意此種方法寫線程必須使用RandomAccessFile,FileOutputStream 會報錯,可能是讀文件時使用文件映射,為保證讀寫*/
讀線程:
RandomAccessFile fis=new RandomAccessFile(file,"rws");
MappedByteBuffer mbb=fis.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, (int)fis.length());
byte[] buf = new byte[(int) fis.length()];
for(int i=0;i<fis.length();i++){
buf[i]= mbb.get(i);
}
/*注意此方法讀線程使用FileInputStream 好像有文件不能同步的問題*/