注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

0与1构筑世界,程序员创造时代

软件架构设计 Java编程

 
 
 

日志

 
 

NIO - 文件锁(笔记)  

2008-10-27 18:18:26|  分类: Java |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

基本概念

文件锁类似于Java中的对象锁,可以锁定整个文件或文件的一部分,又分为独占锁、共享锁。
独占锁:也称排它锁,如果一个线程获得一个文件的独占锁,那么其它线程就不能再获得同一文件的独占锁或共享锁,直到独占锁被释放。
共享锁:如果一个线程获得一个文件的共享锁,那么其它线程可以获得同一文件的共享锁或同一文件部分内容的共享锁,但不能获取排它锁。

示例代码

FileLockThread.java

/**
 * 建立时间:2008-10-28
 */
package cn.aofeng.nio;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import cn.aofeng.util.IOUtils;

/**
 * 测试NIO中的文件锁:三个线程争抢文件锁,获得锁后向文件中写数据,然后再释放文件锁。
 *
 @author aofeng <a href="mailto:aofengblog@163.com>aofengblog@163.com</a>
 */
public class FileLockThread implements Runnable {
   public void run() {
      Thread curr = Thread.currentThread();
      System.out.println("Current executing thread is " + curr.getName());

      URL url = FileLockThread.class.getResource("/cn/aofeng/nio/FileLockThread.txt");
      RandomAccessFile raf = null;
      FileChannel fc = null;
      FileLock lock = null;
      try {
        raf = new RandomAccessFile(url.getPath()"rw");
        fc = raf.getChannel();
        System.out.println(curr.getName() " ready");

        // 轮流获得文件独占锁。
        while (true) {
           try {
              lock = fc.lock();
              break;
           catch (OverlappingFileLockException e) {
              Thread.sleep(1000);
           }
        }

        if (null != lock) {
           System.out.println(curr.getName() " get filelock success");
           fc.position(fc.size());
           fc.write(ByteBuffer.wrap((curr.getName() " write data. ").getBytes()));
        else {
           System.out.println(curr.getName() " get filelock fail");
        }
      catch (FileNotFoundException e) {
        e.printStackTrace();
      catch (IOException e) {
        e.printStackTrace();
      catch (InterruptedException e) {
        e.printStackTrace();
      finally {
        // 注意:要先释放锁,再关闭通道。
        if (null != lock && lock.isValid()) {
           try {
              lock.release();
              System.out.println(curr.getName() " release filelock");
           catch (IOException e) {
              e.printStackTrace();
           }
        }

        IOUtils.close(fc);
        IOUtils.close(raf);
      }
   }

   /**
    @param args
    */
   public static void main(String[] args) {
      Thread t1 = new Thread(new FileLockThread());
      t1.setName("t1");
      Thread t2 = new Thread(new FileLockThread());
      t2.setName("t2");
      Thread t3 = new Thread(new FileLockThread());
      t3.setName("t3");

     
      t1.start();
      t2.start();
      t3.start();
   }
}

代码执行结果

Current executing thread is t1
Current executing thread is t2
Current executing thread is t3
t1 ready
t3 ready
t2 ready
t3 get filelock success
t2 get filelock success
t3 release filelock
t2 release filelock
t1 get filelock success
t1 release filelock

从结果可以看出,各线程轮流获得文件锁,写入数据后然后释放锁。


NIO - 文件锁(笔记) - 傲风 - 宝剑锋从磨砺出 梅花香自苦寒来提示
1)由于各操作系统的锁实现会有不一致的地方,为了使代码方便移植,建议使用独占锁。
2)执行结果在不同的机器或每次执行结果都有可能与上述结果不一致,因为线程的执行顺序无法预料。
3)代码中的IOUtils.java 中的close()方法各位可自行实现或删除示例代码中的两行使用IOUtils.close()的代码,自行写代码关闭随机读写文件对象和文件通道。

<正文结束>


文章声明


作者:傲风(aofengblog@163.com)       编写时间:2008年11月06日

网址:http://aofengblog.blog.163.com

作者保留所有权利,转载请保留文章全部内容或者说明原作者和转载地址!

  评论这张
 
阅读(5886)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017