1.文件锁的定义

  FileLock是文件锁,进程锁,用于进程间并发,控制不同程序(JVM)对同一文件的并发访问。

  FileLock是java 1.4 版本后出现的一个类,它可以通过对一个可写文件(w)加锁,保证同时只有一个进程可以拿到文件的锁,这个进程从而可以对文件做访问;而其它拿不到锁的进程要么选择被挂起等待,要么选择去做一些其它的事情,这样的机制保证了众进程可以顺序访问该文件。

  可以看出,能够利用文件锁的这种性质,在一些场景下,虽然我们不需要向文件中写入数据,不受其他程序的打扰,文件锁就很合适。

  java.nio.channels.FileChannel,FileChannel是NIO中的一个类。

2.独占锁与共享锁

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

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

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

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

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

  所以一个进程中的线程获得了文件锁,希望进程内其他线程可以做读操作时,可以使用共享锁。写操作是不被支持的。

3.使用tryLock来获取锁

   lock()阻塞的方法,锁定范围可以随着文件的增大而增加。

   tryLock()非阻塞,当未获得锁时,返回null。

  FileLock的生命周期:调用FileLock.release()或者Channel.close(),或者JVM关闭。

  boolean java.nio.channels.FileLock.overlaps(long position, long size),true表示当前锁在区域内,false表示当前锁的区域与参数区域不重叠。

 

  文件锁的效果是与操作系统相关的,是由操作系统底层来实现的。比如,在windows下,进程间不能同时读写一个文件,而在Linux下,不同的进程可以同时读写一个文件。

  在读写关键数据时加锁,操作完成后解锁,lock.release();放到finally中。

  一次性申请所有需要的资源,并且在申请不成功的情况下放弃已申请到的资源;  

public class FileLockTest {

    /**

     * 如代码所示,需要进行互斥的进程只要将自己的代码替换掉//互斥操作即可,

     * 每个进程在运行实际逻辑功能代码之前,会尝试获取锁文件锁,

     * 得到文件锁的进程可以继续执行后续的代码,而没有获得锁文件的进程将被操作系统挂起(suspend),

     * 等到其它进程将文件锁释放后再重新开始尝试获取文件锁。

     * 这样子,进程就可以通过FileLock来实现间的互斥运行。

     * @param args

     */

    public static void main(String[] args){

        FileChannel channel = null;

        FileLock lock = null;

        try {

//            对于一个只读文件通过任意方式加锁时会报NonWritableChannelException异常

//            同样对写通道通过有参lock()方式加锁时也会报NonReadableChannelException异常

//            无参lock()默认为独占锁,不会报NonReadableChannelException异常,因为独占就是为了写

//            所谓的共享也只能读共享,写是独占的,共享锁控制的代码只能是读操作

//            channel = new FileOutputStream("logfile.txt",true).getChannel();

            RandomAccessFile raf = new RandomAccessFile("logfile.txt","rw");

            raf.seek(raf.length());//raf在文件末尾追加内容的处理

            channel = raf.getChannel();

//            获得锁方法一lock,阻塞的方法,当文件锁不可用时,当前进程会被挂起

//            lock = channel.lock(0L, Long.MAX_VALUE, true);//共享锁,有写操作会报异常

            lock = channel.lock();//独占锁

//            获得锁方法二trylock,非阻塞的方法,当文件锁不可用时,tryLock()会得到null值

//            do {

//                lock = channel.tryLock();

//            } while(null == lock);

//            互斥操作

            ByteBuffer sendBuffer=ByteBuffer.wrap((new Date()+" 写入\n").getBytes());

            channel.write(sendBuffer);

            Thread.sleep(5000);

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        } catch (InterruptedException e) {

            e.printStackTrace();

        } finally {

            if(lock != null) {

                try {

                    lock.release();

                    lock = null;

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

            if(channel != null) {

                try {

                    channel.close();

                    channel = null;

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

        }

    }

}

/**

 *     间隔一秒钟两次运行本程序,程序会在文件锁的控制下对logfile.txt进行互斥操作

    logfile.txt内容:

    Thu Aug 16 15:39:02 CST 2012 写入

    Thu Aug 16 15:39:07 CST 2012 写入

    当采用第二种方法时,若还未获得文件锁就对文件进行操作,则会报以下异常:

    Exception in thread "main" java.io.IOException: 另一个程序已锁定文件的一部分,进程无法访问。

    at sun.nio.ch.FileDispatcher.write0(Native Method)

    at sun.nio.ch.FileDispatcher.write(Unknown Source)

    at sun.nio.ch.IOUtil.writeFromNativeBuffer(Unknown Source)

    at sun.nio.ch.IOUtil.write(Unknown Source)

    at sun.nio.ch.FileChannelImpl.write(Unknown Source)

    at FileLockTest.main(FileLockTest.java:19)

 */ 

文件锁FileLock的更多相关文章

  1. [转载] 文件锁(Filelock)与锁定映射文件部分内容

    转载自http://jiangzhengjun.iteye.com/blog/517677 文件锁 JDK 1.4引入了文件加锁机制,允许我们同步访问一个共享文件,不过,竞争同一文件的两个线程有可能在 ...

  2. NIO文件锁FileLock

    目录 <linux文件锁flock> <NIO文件锁FileLock> <java程序怎么在一个电脑上只启动一次,只开一个进程> 文件锁可以是shared(共享锁) ...

  3. NIO之FileChannel类的理解和使用

    文章链接:http://blog.csdn.net/qq_16628781/article/details/70532307 知识点: FileChannel类及方法理解: 普通输入输出流复制文件: ...

  4. 20175212童皓桢 《Java程序设计》第六周学习总结

    20175212童皓桢 <Java程序设计>第六周学习总结 教材学习内容总结 第七章 内部类与异常类 1.内部类 Java支持在一个类中定义另一个类,这样的类称作内部类,包含内部类的类称为 ...

  5. 初学io

    IO流: 01.File 创建文件 //创建文件夹 private static void mkdirs() { System.out.println("请您输入创建的文件夹名称:(默认是E ...

  6. Java读取文件加锁代码Demo(利用Java的NIO)

    本博文部分转载于:http://blog.csdn.net/wangbaochu/article/details/48546717 Java 提供了文件锁FileLock类,利用这个类可以控制不同程序 ...

  7. 【java】详解I/O流

    目录结构: contents structure [+] File类 I/O流体系 流的基本介绍 访问文件 转化流 DataInputStream和DataOutputStream 对象流 推回输入流 ...

  8. java程序怎么在一个电脑上只启动一次,只开一个进程

    目录 <linux文件锁flock> <NIO文件锁FileLock> <java程序怎么在一个电脑上只启动一次,只开一个进程> 方案1: 单进程程序可以用端口绑定 ...

  9. Java程序设计——对象序列化

    对象序列化的目标是将对象保存到磁盘中或允许在网络中直接传输对象,对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久保存在磁盘上,通过网络将这种二进制流传输到另 ...

随机推荐

  1. Codeforces Round #345 (Div. 2)【A.模拟,B,暴力,C,STL,容斥原理】

    A. Joysticks time limit per test:1 second memory limit per test:256 megabytes input:standard input o ...

  2. [bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式 (hash构造后缀数组,二分答案)

    以后似乎终于不用去学后缀数组的倍增搞法||DC3等blablaSXBK的方法了= = 定义(来自关于后缀数组的那篇国家集训队论文..) 后缀数组:后缀数组SA是一个一维数组,它保存1..n的某个排列S ...

  3. 解决php的sha1和java的sha1(DigestUtils.sha1Hex)产生的字符串不相等的问题

    最近对接某个第三方服务,其中对接某些api需要用到他们的签名回调,根据他们传来的get参数和apiSecret进行拼接并使用sha1加密,然后返回弄成jsonp的格式返回,出于菜鸟的本能,首先是下载了 ...

  4. 关于数据库timestamp类型问题

    数据库使用timestamp类型字段,默人时间为0000-00-00 00:00:00 于是后台会报java.sql.SQLException: Value '0000-00-00 00:00:00' ...

  5. 最小生成数之Kruskal算法

    描述 随着小Hi拥有城市数目的增加,在之间所使用的Prim算法已经无法继续使用了--但是幸运的是,经过计算机的分析,小Hi已经筛选出了一些比较适合建造道路的路线,这个数量并没有特别的大. 所以问题变成 ...

  6. 学习JVM-GC收集器

    1. 前言 在上一篇文章中,介绍了JVM中垃圾回收的原理和算法.介绍了通过引用计数和对象可达性分析的算法来筛选出已经没有使用的对象,然后介绍了垃圾收集器中使用的三种收集算法:标记-清除.标记-整理.标 ...

  7. 织梦CMS提示DedeTag Engine Create File False错误的解决办法总结

    今天帮客户升级站点,遇到了一个老问题,生成栏目的时候提示"DedeTag Engine Create File False",突然发觉这个问题竟然在以前做站的时候困扰过我多次,于是 ...

  8. ios7对于NSString对象进行了的变更

    1.instancetype替代id来做返回值的类型.

  9. iOracle实战笔记(第五天)

    导读 今天的主要内容:维护数据的完整性.索引.管理Oracle的权限和角色. 一.维护数据库的数据的完整性 数据完整性用于确保数据库数据遵从一定的商业规则和逻辑规则.在Oracle中,数据完整性可以使 ...

  10. linux的nvme驱动需要关心的统计项

    blk-mq-sysfs.c生成了一些其他的nvme的统计项, 有多少个online的cpu,在驱动加载的时候会默认生成多少个队列,除非内存不足或者在保留内核中,则会减少. [root@localho ...