给某一个文件加锁,防止并发访问时引起的数据不安全。
在 JUC 中,可以使用 synchronized、Lock 给共享的资源加锁,或者使用 volatile、CAS 算法等防止并发冲突。在 FileChannel 中也提供了类似 Lock 的加锁方式。
public abstract FileLock lock(long position, long size, boolean shared) throws IOException;
shared 参数说明。
true:共享锁。实际上是指“读共享”,某一线程将资源锁住之后,其他线程既只能读、不能写该资源。
false:独占锁。某一线程将资源锁住之后,其他线程既不能读、也不能写该资源。
package nio;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
public class FileLockTest {
public static void main(String[] args) throws FileNotFoundException, IOException, InterruptedException {
RandomAccessFile raf = new RandomAccessFile("g:/abc.txt", "rw");
FileChannel fileChannel = raf.getChannel();
/*
将 abc.txt 中 position=2,size=4 的内容加锁(即只对文件的部分内容加了锁)。
lock()第三个布尔参数的含义如下:
true:共享锁。实际上是指“读共享”:某一线程将资源锁住之后,其他线程既只能读、不能写该资源。
false:独占锁。某一线程将资源锁住之后,其他线程既不能读、也不能写该资源。
*/
// FileChannel 加共享锁
FileLock fileLock = fileChannel.lock(2, 4, true);
new Thread(
() -> {
try {
byte[] bs = new byte[8];
// 新线程对 abc.txt 进行读操作
raf.read(bs,0,8);
// 新线程对 abc.txt 进行写操作
// raf.write("ccccccccc".getBytes(),0,8);
} catch (Exception ex) {
ex.printStackTrace();
}
}).start();
// 模拟main线程将abc.txt锁3秒的操作
System.out.println("main线程将abc.txt锁3秒...");
Thread.sleep(3000);
System.out.println("3秒结束,main释放锁");
fileLock.release();
}
}
main线程将abc.txt锁3秒...
3秒结束,main释放锁
main线程将abc.txt锁3秒...
java.io.IOException: 另一个程序已锁定文件的一部分,进程无法访问。
at java.io.RandomAccessFile.writeBytes(Native Method)
at java.io.RandomAccessFile.write(RandomAccessFile.java:525)
at nio.FileLockTest.lambda$main$0(FileLockTest.java:28)
at java.lang.Thread.run(Thread.java:748)
3秒结束,main释放锁
main线程将abc.txt锁3秒...
3秒结束,main释放锁
main线程将abc.txt锁3秒...
3秒结束,main释放锁
修改前文件内容
helloworld
修改后文件内容
ccccccccld
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/chengqiuming/article/details/124894457
内容来源于网络,如有侵权,请联系作者删除!