对映射文件的部分加锁
? 文件映射通常应用于极大的文件,我们可能需要对这种巨大的文件进行部分加锁,以便其他进程可以修改文件中未被加锁的部分。例如:数据库就是这样,因此多个用户可以同时访问它。
看个例子:连个线程分别对文件的不同部分加锁:
package com.wjy.nio;import java.io.FileNotFoundException;import java.io.IOException;import java.io.RandomAccessFile;import java.nio.ByteBuffer;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel;import java.nio.channels.FileLock;public class LockingMappedFiles {static final int LENGTH=0x8FFFFFF;static FileChannel fc;public static void main(String args[]){try {fc=new RandomAccessFile("./file/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);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}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 {FileLock fl=fc.lock(start, end, false);System.out.println("Locked: "+start+" to "+end);while(buff.position()<buff.limit()-1){buff.put((byte)(buff.get()+1));}fl.release();System.out.println("Release: "+start+" to "+end);} catch (Exception e) {// TODO: handle exception}}}}
?注意这里是一个对缓冲区分片的操作:
mbb.limit(end); //设置尾部 mbb.position(start); //设置开头 buff=mbb.slice(); //分片
?