Java nio 文件锁一例
Java nio 文件锁一例
Java nio 文件锁一例“:
- package 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);// 改变此位置的值
- }
- }
评论暂时关闭