对映射文件的部分加锁

如前面提到的,文件映射通常应用于极大的文件。因此我们可能需要对如此巨大的文件进行
部分加锁,以便其他进程可以修改文件中未被加锁的部分。例如,数据库就是这样,因此多
个用户可以同时访问到它。


下面例子中有两个线程,分别加锁文件的不同部分。


//: c12:LockingMappedFiles.java
// Locking portions of a mapped file.
// {RunByHand}
// {Clean: test.dat}
import java.io.*;
import java.nio.*;
import java.nio.channels.*;


public class LockingMappedFiles {
    static final int LENGTH = 0x8FFFFFF; // 128 Mb
  static FileChannel fc; 
    public static void main(String[] args) throws Exception {
        fc =   
      new RandomAccessFile("test.dat", "rw").getChannel();
    MappedByteBuffer out = 
      fc.map(FileChannel.MapMode.READ_WRITE, 0, LENGTH);
        for(int i = 0; i < LENGTH; i++)
      out.put((byte)'x');
        new LockAndModify(out, 0, 0 + LENGTH/3);
    new LockAndModify(out, LENGTH/2, LENGTH/2 + LENGTH/4);
    } 
    private static class LockAndModify extends Thread {
    private ByteBuffer buff;
    private int start, end;
        LockAndModify(ByteBuffer mbb, int start, int end) {
            this.start = start; 
            this.end = end; 
      mbb.limit(end);
      mbb.position(start);
      buff = mbb.slice();
            start(); 
        }         
    public void run() {
            try { 
                // Exclusive lock with no overlap: 
        FileLock fl = fc.lock(start, end, false); 
        System.out.println("Locked: "+ start +" to "+ end);
        // Perform modification:
        while(buff.position() < buff.limit() - 1)
          buff.put((byte)(buff.get() + 1)); 
                fl.release(); 
        System.out.println("Released: "+start+" to "+ end);
            } catch(IOException e) { 
        throw new RuntimeException(e);
            } 
        } 
    } 
} ///:~


线程类 LockAndModify 创建了缓冲区和用于修改的 slice( ),然后在 run()中,获得文
件通道上的锁(我们不能获得缓冲器上的锁——只能是通道上的)。lock()调用类似于在
一个工程上获得线程锁——我们现在处在“临界区”,即对该部分的文件具有独占访问权。


如果有 Java 虚拟机,它会自动释放锁,或者关闭加锁的通道。不过我们也可以像程序中那

样,显式地为 FileLock 调用 release()释放锁。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值