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. Python系列之入门篇——HDFS

    Python系列之入门篇--HDFS 简介 HDFS (Hadoop Distributed File System) Hadoop分布式文件系统,具有高容错性,适合部署在廉价的机器上.Python ...

  2. 番外篇--Moddule Zero介绍

    1.1 ABPZero - 概述 介绍 微软ASP.NET身份框架 权限 会话 角色管理 默认角色 用户管理 多租户 设置管理 审计日志 1.1.1 介绍 Modulde Zero实现了ASP.NET ...

  3. 学而精计算机公共基础学习之路TEST1

    算法 一:算法基本概念 算法是个什么概念学了这么久的程序尽然没有听说过,其实算法就是为了解决问题那么怎么准确完整的解决这个问题就是算法.所以我们所写的程序就可以说为对算法的描述,但是程序编制是不能有于 ...

  4. linux 下查看有当前文件夹有多少个文件

    ls |wc -w

  5. 怎么知道我的laravel 是几版本的

    方法1: 使用php artisan --version ,只要能看懂这个命令的人一定已经具有初步的Laravel知识. 再介绍一种不需要命令,直接去文件中去查看的方法. 方法2: 在项目文件中找ve ...

  6. 织梦DedeCMS提示信息框的修改,修改ShowMsg方法函数

    http://www.360doc.com/content/14/0408/13/16498929_367236469.shtml 织梦DedeCMS系统,处处都在用到提示信息,但是这个提示框,前台后 ...

  7. ASP.NET网络爬虫小研究 HtmlAgilityPack基础,爬取数据保存在数据库中再显示再自己的网页中

    1.什么是网络爬虫 关于爬虫百度百科这样定义的:网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些 ...

  8. MySQL事务隔离级别的实现原理

    回顾 在MySQL的众多存储引擎中,只有InnoDB支持事务,所有这里说的事务隔离级别指的是InnoDB下的事务隔离级别. 读未提交:一个事务可以读取到另一个事务未提交的修改.这会带来脏读.幻读.不可 ...

  9. SQL Server中字段类型对应的C#中的数据类型

      数据库  C#程序  int                int32  text string bigint int64 binary System.Byte[] bit Boolean cha ...

  10. Ring3句柄表的枚举

    由于windows并没有给出枚举所有句柄所用到的API,要获得句柄,我们必须使用未公开的Native API才可以,使用如下函数: NTSTATUS WINAPI NtQuerySystemInfor ...