線程和進(jìn)程 對(duì)文件鎖的操作(RandomAccessFile MappedByteBuffer FileLock)
1.文件鎖的分類(lèi)文件鎖分為阻塞式文件鎖和非阻塞式的文件鎖,可以通過(guò)new FileChannel().tryLock /lock,后者是阻塞式,阻塞式意思是指當(dāng)前進(jìn)程沒(méi)有獲得文件鎖即刻等待直到有進(jìn)程將對(duì)應(yīng)文件的鎖釋放。
2.文件鎖針對(duì)進(jìn)程
這里指進(jìn)程的原因是因?yàn)閷?duì)文件鎖而言一個(gè)線程同一時(shí)間段對(duì)同一個(gè)文件只能加上一把鎖,只有等待當(dāng)前線程釋放掉后,才能繼續(xù)對(duì)文件加鎖,不然會(huì)報(bào)OverlappingFileLockException的錯(cuò)誤,所以文件鎖是進(jìn)程間的鎖。
3.線程間預(yù)防重復(fù)加鎖,減少讀寫(xiě)文件等待時(shí)間
//給該文件加鎖
RandomAccessFile fis = new RandomAccessFile(file, "rws"); //單一線程的讀寫(xiě)同步
FileChannel fcin=fis.getChannel(); // 獲得文件通道
FileLock flin=null; //聲明文件鎖對(duì)象
int operateNum=10; //若文件鎖一直別占用,設(shè)置最大讀取次數(shù)為10次,超出次數(shù)表示文 //件不可讀,
For(int i=0;i<operateNum,i++){
try {
flin = fcin.tryLock(); // 獲取文件非阻塞鎖,如果不能獲取,繼續(xù)等待0.5s.
break;
} catch (Exception e) {
System.out.println("有其他線程正在操作該文件,當(dāng)前線程休眠500毫秒");
sleep(500);
If((i+1)>=operateNum){
Throw e //文件被強(qiáng)制占用 ,處于不可讀的狀態(tài)
}
}
}
//獲取成功
//進(jìn)行文件的讀或?qū)懙牟僮?br /> RandomAccessFile 流中讀出文件的數(shù)據(jù);
RandomAccessFile 流向該文件寫(xiě)入新數(shù)據(jù);
//該文件的操作完畢,釋放該文件鎖和相關(guān)資源
flin.release();
fcout.close();
out.close();
4.線程寫(xiě)文件加鎖后,讀文件線程不需加鎖的方法(保證讀寫(xiě)同步)
寫(xiě)線程:
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("**********************************文件被操作,寫(xiě)文件線程休眠0.2m");
Thread.sleep(200);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
/*注意此種方法寫(xiě)線程必須使用RandomAccessFile,F(xiàn)ileOutputStream 會(huì)報(bào)錯(cuò),可能是讀文件時(shí)使用文件映射,為保證讀寫(xiě)*/
讀線程:
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 好像有文件不能同步的問(wèn)題*/
posted on 2012-10-26 18:34 Tom Xu 閱讀(4209) 評(píng)論(1) 編輯 收藏