Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 313|回复: 0

[JavaIO学习]java中的文件锁

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-3 23:58:25 | 显示全部楼层 |阅读模式
    在对文件操作过程中,有时候需要对文件进行加锁操作,防止其他线程访问该文件。对文件的加锁方法有两种:

    第一种方法:使用RandomAccessFile类操作文件。
        在java.io.RandomAccessFile类的open方法,提供了参数实现独占的方式打开文件:
          RandomAccessFile raf = new RandomAccessFile(file, "rws");
    其中的“rws”参数,rw代表读取和写入,s代表了同步方式,也就是同步锁。这种方式打开的文件,就是独占方式的。

    第二种方法:使用sun.nio.FileChannel对文件进行加锁。
    代码:
    1. RandomAccessFile raf = new RandomAccessFile("file.txt", "rw");
    2.       FileChannel fc = raf.getChannel();
    3.       FileLock fl = fc.tryLock();
    4.       if(fl.isValid())
    5.           System.out.println("You have got the file lock.");
    6.                   
    7. 以上是通过RandomAccessFile来获得文件锁的,那么在写文件的时候如何对文件加锁呢?方法如下:
    8. 代码:
    9.         FileOutputStream fos = new FileOutputStream("file.txt");
    10.         FileChannel fc = fos.getChannel(); //获取FileChannel对象
    11.         FileLock fl = fc.tryLock();  //or fc.lock();
    12.         if(null != fl)
    13.              System.out.println("You have got file lock.");
    14.         //TODO write content to file
    15.         //TODO write end, should release this lock
    16.         fl.release(); //释放文件锁  
    17.         fos.close;  //关闭文件写操作

    18.      如果在读文件操作的时候,对文件进行加锁,怎么操作呢?从API文档中我们可以看到,
    19. FileChannel也可以从FileInputStream中直接获得,但是这种直接获得FileChannel的对象直接去
    20. 操作FileLock会报异常NonWritableChannelException,这样我们又怎么去获得文件锁呢?
    21. 需要自己去实现getChannel方法,代码如下:
    22.    private static FileChannel getChannel(FileInputStream fin, FileDescriptor fd) {
    23.             FileChannel channel = null;
    24.                 synchronized(fin){
    25.                         channel = FileChannelImpl.open(fd, true, true, fin);
    26.                         return channel;
    27.                  }
    28.      }
    复制代码
        其实,我们看FileInputStream时,发现getChannel方法与我们写的代码只有一个地方不同,即open方法的第三个参数不同,如果设置为false,就不能锁住文件了。缺省的getChannel方法,就是false,因此,不能锁住文件。 通过对 FileChannel 调用 tryLock() 或 lock() ,就可以获得整个文件的 FileLock  Trylock 与 lock 方法     tryLock() 是非阻塞式的,它设法获取锁,但如果不能获得,例如因为其他一些进程已经持有相同的锁,而且不共享时,它将直接从方法调用返回。     lock() 是阻塞式的,它要阻塞进程直到锁可以获得,或调用 lock() 的线程中断,或调用 lock() 的通道关闭。     对独占锁和共享锁的支持必须由底层的操作系统提供。锁的类型可以通过 FileLock.iSSHared() 进行查询。另外,我们不能获取缓冲器上的锁,只能是通道上的。

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

    共享锁 :如果一个线程获得一个文件的共享锁,那么其它线程可以获得同一文件的共享锁或同一文件部分内容的共享锁,但不能获取排它锁  当 a.txt 文件被加独占锁时 其他线程不可读也不可写
    当 a.txt 文件被加共享锁时 其他线程可读也不可写  如何获得共享锁     fc.tryLock(position,size,isShare); 第三个参数为 true 时 为共享锁
    例:
    1. import java.io.*;
    2. import java.net.InetAddress;
    3. import java.nio.ByteBuffer;
    4. import java.nio.channels.FileChannel;
    5. import java.nio.channels.FileLock;
    6. import java.nio.channels.OverlappingFileLockException;
    7. import javax.servlet.ServletException;
    8. import javax.servlet.http.HttpServlet;
    9. import javax.servlet.http.HttpServletRequest;
    10. import javax.servlet.http.HttpServletResponse;
    11. public class TestServlet extends HttpServlet {
    12.       protected void service(HttpServletRequest request,
    13.             HttpServletResponse response) throws ServletException, IOException {
    14.         File f = new File("F://kankan//opt.txt");
    15.         RandomAccessFile fi = new RandomAccessFile(f, "rw");
    16.         FileChannel fc = fi.getChannel();
    17.         FileLock fl = null;
    18.         Thread t = Thread.currentThread();
    19.         System.out.println(t.getId() + " " + t.getName());
    20.         InetAddress address = InetAddress.getLocalHost();
    21.         
    22.         try {
    23.             try {
    24.                 fl = fc.tryLock();
    25.                 if (fl == null) {
    26.                     System.out.println(address.getHostAddress() + " wait 5 sec for reason (null)!");
    27.                     throw new OverlappingFileLockException();
    28.                 }
    29.             } catch (OverlappingFileLockException e) {
    30.                 System.out.println(address.getHostAddress() + " wait 5 sec once!");
    31.                 try {
    32.                     Thread.sleep(5 * 1000);
    33.                 } catch (InterruptedException e1) {
    34.                     e1.printStackTrace();
    35.                 }
    36.                 try {
    37.                     fl = fc.tryLock();
    38.                     if (fl == null) {
    39.                         System.out.println(address.getHostAddress() + " wait 5 sec for reason (null)!");
    40.                         throw new OverlappingFileLockException();
    41.                     }
    42.                 } catch (OverlappingFileLockException oe) {
    43.                     System.out.println(address.getHostAddress()+ " cannot get file lock!");
    44.                     throw new OverlappingFileLockException();
    45.                 }
    46.             }
    47.             if (fl != null) {
    48.                 System.out.println(address.getHostAddress() + " start write!");
    49.                 fc.position(fc.size());
    50.                 fc.write(ByteBuffer
    51.                  .wrap((address.getHostAddress() + " =============1=============== /r/n")
    52.                  .getBytes()));
    53.                 System.out.println(address.getHostAddress() + " stop write!");
    54.             }
    55.         } catch (Exception e) {
    56.             System.out.println(address.getHostAddress()+ " exception or cannot get file lock!");
    57.             response.getWriter().write(address.getHostAddress()
    58.                     + " exception or cannot get file lock!");
    59.             return;
    60.         } finally {
    61.             if (null != fl && fl.isValid()) {
    62.                 fl.release();
    63.                 System.out.println(address.getHostAddress() + " release filelock");
    64.             }
    65.             fc.close();
    66.             fi.close();
    67.         }
    68.     }
    69. }
    复制代码

       
         
         
          
          

            
          

            
          
         
       

      


    源码下载:http://file.javaxxz.com/2014/11/3/235825531.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 13:50 , Processed in 0.351083 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表