java nio 文件锁小例

 ackage com.jacp.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;  
 /** 
  * 对内存中文件加锁 
  * @author jacp 
  * 
  */  
 public class MyFileLock {  
     private static final int BSIZE = 60;  
     private static FileChannel fc;  
     public static void main(String[] args) {  
         try {  
             fc = new RandomAccessFile("test.dat", "rw").getChannel();  
             MappedByteBuffer mapBuffer = fc.map(FileChannel.MapMode.READ_WRITE, 0, BSIZE);  
             for(int i = 0; i < BSIZE; i++) {  
                 mapBuffer.put((byte)'a');  
             }  
               
             // 三个线程分别修改不同的地方   
             mapBuffer.position(BSIZE/4);  
             mapBuffer.limit(2*BSIZE/3);  
             ByteBuffer buffer = mapBuffer.slice();  
             new LockAndModify(mapBuffer, 0, BSIZE/3);  
             new LockAndModify(mapBuffer, BSIZE/2, BSIZE);  
             while(buffer.hasRemaining()) {  
                 modify(buffer);  
             }  
               
             Thread.sleep(1000);// 此处要延迟,不然看不到效果  
             mapBuffer.rewind();  
             System.out.println(mapBuffer.limit());  
             while(mapBuffer.hasRemaining()) {// 查看三个线程的修改效果  
                 System.out.print((char)mapBuffer.get());  
             }  
               
         } catch (FileNotFoundException e) {  
             e.printStackTrace();  
         } catch (IOException e) {  
             e.printStackTrace();  
         } catch (InterruptedException e) {  
             e.printStackTrace();  
         }  
           
     }  
       
     /* 
      * capacity 为ByteBuffer的大小,在ByteBuffer创建时就被指定 
      * position 为当前读/写操作数据的下标位置 
      * limit 为ByteBuffer中有效数据的长度,在进行写操作时和capacity相等 
      * mark 一个临时存放的位置下标。调用mark()会将mark设为当前的position的值, 
      *      以后调用reset()会将position属性设置为mark的值。mark的值总是小于等于position的值, 
      *      如果将position的值设的比mark小,当前的mark值会被抛弃掉。 
      *  
      * Buffer clear() 
      *      把position设为0,把limit设为capacity,一般在把数据写入Buffer前调用。 
      * Buffer flip() 
      *      把limit设为当前position,把position设为0,一般在从Buffer读出数据前调用。 
      * Buffer rewind() 
      *      把position设为0,limit不变,一般在把数据重写入Buffer前调用。 
      */  
     private static class LockAndModify extends Thread {  
         private ByteBuffer buffer;  
         private int start;  
         private int end;  
         public LockAndModify(ByteBuffer buffer, int start, int end) {  
             buffer.limit(end);  
             buffer.position(start);  
             this.buffer = buffer.slice();// 创建新的缓冲区长度为end-start  
             this.start = start;  
             this.end = end;  
             start();  
         }  
           
         public void run() {  
             try {  
                 FileLock fl = fc.lock(start, end, false);// 锁住文件的一部分  
                 while(buffer.position() < buffer.limit()) {  
                     modify(buffer);  
                 }  
                   
                 fl.release();// 释放锁  
                   
             } catch (IOException e) {  
                 e.printStackTrace();  
             }  
         }  
           
     }  
       
     /** 
      * 修改byteBuffer中的值 
      * @param buffer 
      */  
     public static void modify(ByteBuffer buffer) {  
         buffer.mark();// 记住此位置  
         byte b = (byte)(buffer.get()+1);// 读取一个,下标移动到后一位置  
         buffer.reset();// 将下标回到mark()位置  
         buffer.put(b);// 改变此位置的值  
     }  
 } 


你可能感兴趣的:(java nio 文件锁小例)