博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java处理多人同时读写文件的文件锁处理
阅读量:5067 次
发布时间:2019-06-12

本文共 4508 字,大约阅读时间需要 15 分钟。

原文转载自

 

最近项目中有遇到并发同时访问一个文件读写的情况、但是同时读写就会出错、所以我研究了一下java文件锁这个机制下面直接贴代码

我通过的是线程来模拟多人同时读写的情况

写文件

package com.dnion.test;import java.io.File;import java.io.IOException;import java.io.RandomAccessFile;import java.nio.channels.FileChannel;import java.nio.channels.FileLock;import java.util.Calendar;/** * @author chb */public class Thread_writeFile extends Thread{    public void run(){        Calendar calstart=Calendar.getInstance();        File file=new File("D:/test.txt");                try {            if(!file.exists())                file.createNewFile();                                    //对该文件加锁            RandomAccessFile out = new RandomAccessFile(file, "rw");            FileChannel fcout=out.getChannel();            FileLock flout=null;            while(true){                  try {                    flout = fcout.tryLock();                    break;                } catch (Exception e) {                     System.out.println("有其他线程正在操作该文件,当前线程休眠1000毫秒");                      sleep(1000);                  }                            }                    for(int i=1;i<=1000;i++){                sleep(10);                StringBuffer sb=new StringBuffer();                sb.append("这是第"+i+"行,应该没啥错哈 ");                out.write(sb.toString().getBytes("utf-8"));            }                        flout.release();            fcout.close();            out.close();            out=null;        } catch (IOException e) {            e.printStackTrace();        } catch (InterruptedException e) {            e.printStackTrace();        }        Calendar calend=Calendar.getInstance();        System.out.println("写文件共花了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"秒");    }}

 

  读文件

package com.dnion.test;import java.io.File;  import java.io.FileInputStream;  import java.io.FileNotFoundException;  import java.io.IOException;  import java.io.RandomAccessFile;import java.nio.channels.FileChannel;  import java.nio.channels.FileLock;  import java.util.Calendar;  /**  * @author chb  */  public class Thread_readFile extends Thread{      public void run(){          try {              Calendar calstart=Calendar.getInstance();              sleep(5000);              File file=new File("D:/test.txt");                                //给该文件加锁              RandomAccessFile fis = new RandomAccessFile(file, "rw");             FileChannel fcin=fis.getChannel();              FileLock flin=null;              while(true){                  try {                    flin = fcin.tryLock();                    break;                } catch (Exception e) {                     System.out.println("有其他线程正在操作该文件,当前线程休眠1000毫秒");                      sleep(1000);                  }                            }              byte[] buf = new byte[1024];              StringBuffer sb=new StringBuffer();              while((fis.read(buf))!=-1){                                  sb.append(new String(buf,"utf-8"));                      buf = new byte[1024];              }                            System.out.println(sb.toString());                            flin.release();              fcin.close();              fis.close();              fis=null;                            Calendar calend=Calendar.getInstance();              System.out.println("读文件共花了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"秒");          }catch (FileNotFoundException e) {              e.printStackTrace();          } catch (IOException e) {              e.printStackTrace();          } catch (InterruptedException e) {              e.printStackTrace();          }      }  }

  

调用

 

这里我们要讲解一下文件锁

 

 

我们通过RandomAccessFile这个随机读取流来操作文件速度上面会有一点慢、但不是极其大的文件一般可以忽略。

我们通过FileChannel对象来获得锁

 

Trylock 与lock方法

tryLock()是非阻塞式的,它设法获取锁,但如果不能获得,例如因为其他一些进程已经持有相同的锁,而且不共享时,它将直接从方法调用返回。

lock()是阻塞式的,它要阻塞进程直到锁可以获得,或调用lock()的线程中断,或调用lock()的通道关闭。

对独占锁和共享锁的支持必须由底层的操作系统提供。锁的类型可以通过FileLock.isShared()进行查询。另外,我们不能获取缓冲器上的锁,只能是通道上的。

OverlappingFileLockException 与锁的作用域

    在某个文件加锁锁只会作用在此文件上对其他文件无效

    单个 Java 虚拟机在某个特定文件上所保持的锁定是不重叠的,即同一个jvm中不同线程去拿同一文件的锁时,先拿到的获得锁,后获取的无法获得锁,tryLock()方法不会抛出异常,但获得锁值为null。

       不同jvm或者不同操作系统获取同一文件锁时,先拿到的获得锁,后获取的抛出文件重叠锁异常【OverlappingFileLockException】。以上是windows才会出现如此现象,如果是linux 会抛出异常:【java.io.IOException:Permission denied】

 

共享锁与独占锁区别

独占锁:也称排它锁,如果一个线程获得一个文件的独占锁,那么其它线程就不能再获得同一文件的独占锁或共享锁,直到独占锁被释放。

共享锁:如果一个线程获得一个文件的共享锁,那么其它线程可以获得同一文件的共享锁或同一文件部分内容的共享锁,但不能获取排它锁

 

当a.txt文件被加独占锁时 其他线程不可读也不可写

当a.txt文件被加共享锁时 其他线程可读也不可写

 

如何获得共享锁

       fc.tryLock(position,size,isShare);第三个参数为true时 为共享锁

转载于:https://www.cnblogs.com/xingwu/p/4021928.html

你可能感兴趣的文章
nodejs fs路径
查看>>
动态规划算法之最大子段和
查看>>
linux c:关联变量的双for循环
查看>>
深入浅出理解zend framework(三)
查看>>
python语句----->if语句,while语句,for循环
查看>>
javascript之数组操作
查看>>
一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别...
查看>>
C#6新特性,让你的代码更干净
查看>>
LinkedList源码分析
查看>>
TF-IDF原理
查看>>
用JS制作博客页面背景随滚动渐变的效果
查看>>
JavaScript的迭代函数与迭代函数的实现
查看>>
一步步教你学会browserify
查看>>
Jmeter入门实例
查看>>
亲近用户—回归本质
查看>>
中文脏话识别的解决方案
查看>>
CSS之不常用但重要的样式总结
查看>>
Python编译错误总结
查看>>
URL编码与解码
查看>>
日常开发时遇到的一些坑(三)
查看>>