`
qianshangding
  • 浏览: 124696 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

文件锁-FileLock

 
阅读更多
最近在看flume部分功能的源码,关于FileLock的使用,其实在很多开源框架都有涉及,我所看过的有lucene,zookeeper,hadoop,es等开源框架都有用到,下面简单的介绍下FileLock。

1,FileLock是独占锁,控制不同程序(JVM)对同一文件的并发访问。
2,可以对写文件(w)加锁,而且必须是可写文件,不然回报:java.nio.channels.NonWritableChannelException异常,这样可以保证只有同一个进程才能拿到锁对文件访问。其他进程无法访问改文件,或者删除该文件的目录。

3,由于是独占锁,所以可以保证进程间顺序访问该文件,避免数据错误。s

4,FileLock的生命周期,在调用FileLock.release(),或者Channel.close(),或者JVM关闭,则生命周期结束。

5,FileLock的lock和tryLock只能调用一次,释放后才能继续获得锁。


java.io.File.deleteOnExit()FileLock生命周期结束是,文件被删除,一般会用于临时文件的删除。强制关闭虚拟机,是不会删除文件的。测试代码:

public static void main(String[] args) throws IOException {

    File f = null;

    try {

        f = File.createTempFile("tmp", ".txt");

        System.out.println("Path: " + f.getAbsolutePath());

        f.deleteOnExit();

        f = File.createTempFile("tmp", null);

        System.out.print("Path: " + f.getAbsolutePath());

        f.deleteOnExit();

    } catch (Exception e) {

        e.printStackTrace();

    }

 }

获取了FileLock独占锁的文件,通过delete是无法删除的,可以通过deleteOnExit()在FileLock生命周期结束的时候删除,测试代码:

    FileLock fileLock = null;
    File file = new File("D:\\trylock\\", "fish.lock");
    RandomAccessFile randAccessfile = new RandomAccessFile(file, "rws");
    // 获取独占锁,阻塞的方法,当文件锁不可用时,当前进程会被挂起
    // randAccessfile.getChannel().lock();
    // 获取独占锁,非阻塞的方法,当文件锁不可用时,tryLock()会得到null值
    fileLock = randAccessfile.getChannel().tryLock();
    if (fileLock != null && file.isDirectory()) {
        file.delete();
    } else if (fileLock != null && file.isFile()) {
//	        file.delete();// 删除没效果,必须使用deleteOnExit
        file.deleteOnExit();// 虚拟机退出,就删除了
    }
    if (fileLock == null) {
        return;
    } else {
        fileLock.release();
        fileLock.channel().close();
        fileLock = null;
    }

Flume中的使用:

private FileLock tryLock(File dir) throws IOException {
    File lockF = new File(dir, FILE_LOCK);
    lockF.deleteOnExit();
    RandomAccessFile file = new RandomAccessFile(lockF, "rws");
    FileLock res = null;
    try {
      res = file.getChannel().tryLock();
    } catch(OverlappingFileLockException oe) {
      file.close();
      return null;
    } catch(IOException e) {
      LOGGER.error("Cannot create lock on " + lockF, e);
      file.close();
      throw e;
    }
    return res;
  }

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics