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 好像有文件不能同步的问题*/