import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileLock;
/**
* 文件枷锁
* 允许我们同步访问某个作为共享资源的文件
* 同一个文件的两个线程可能在不同的java虚拟机上,或者一个是java线程,另一个是操作系统中其他的某个本地线程
* 文件锁对其他的操作系统进程是课件的,因为java的文件加锁直接映射到了本地操作的加锁工具
*/
public class FileLocking {
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("file.txt");
/*
调用tryLock或者lock 可以获得整个文件的FileLock tryLock是非组赛的,他设法获取锁。但是如果不能获得,
它直接从方法调用返回
Lock是阻塞的,他要阻塞进程直至锁可以获得,或调用lock的线程终端,或调用lock的通道关闭,使用FileLock.release()可以释放锁
其中两个方法中position和size根据尺寸大小进行枷锁,shared判断是否共享锁
其中FlieLock.isShared进行查询 锁的类型
*/
FileLock fileLock = fileOutputStream.getChannel().tryLock();
if (fileLock != null) {
System.out.println("Locked File");
fileLock.release();
System.out.println("Released Lock");
}
fileOutputStream.close();
}
}
对映射文件的部分加锁
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 LENGIN = 0x8FFFFFF;
static FileChannel fc;
public static void main(String[] args) throws IOException {
fc = new RandomAccessFile("test.dat", "rw").getChannel(); // 获取相关的FileChannel
MappedByteBuffer map = fc.map(FileChannel.MapMode.READ_WRITE, 0, LENGIN);
for (int i = 0; i < LENGIN; i++) {
map.put((byte)'x');
}
new LockAndModify(map,0,0+LENGIN/3);
new LockAndModify(map,LENGIN/2,LENGIN/2+LENGIN/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(); //创建缓冲区和用修改的slice
start();
}
public void run() {
try {
FileLock lock = fc.lock(start, end, false);
System.out.println("Locked: " +start + " to: " +end);
while (buff.position() < buff.limit() -1){
buff.put((byte)(buff.get()+1));
}
lock.release(); //释放锁
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}