转载请注明原创出处,谢谢!
上篇NIO相关基础篇一,主要介绍了一些基本的概念以及缓冲区(Buffer)和通道(Channel),本篇继续NIO相关话题内容,主要就是文件锁、以及比较关键的Selector,后续还会继续有一到二篇左右与NIO内容相关。
文件锁(FileLock)
在看RocketMQ源码中,发现有关于文件锁的import,但是具体使用代码里面注释调了[回头看看为什么,理解下,到时候会在某篇文章里进行说明](实现一个事情的方法很多,所以不一定就一种),但是为了知识的完整性,还是准备讲下文件锁,可能以后或者那个地方可以使用,或者大家在那里使用到都可以继续留言讨论。
文件锁和其他我们了解并发里面的锁很多概念类似,当多个人同时操作一个文件的时候,只有第一个人可以进行编辑,其他要么关闭(等第一个人操作完成之后可以操作),要么以只读的方式进行打开。
在java nio中提供了新的锁文件功能,当一个线程将文件锁定之后,其他线程无法操作此文件,文件的锁操作是使用FileLock类来进行完成的,此类对象需要依赖FileChannel进行实例化。
文件锁方式:
- 共享锁:允许多个线程进行文件读取。
- 独占锁:只允许一个线程进行文件的读写操作。
备注:文件锁定以整个 Java 虚拟机来保持。但它们不适用于控制同一虚拟机内多个线程对文件的访问。
多个并发线程可安全地使用文件锁定对象。
Java文件依赖FileChannel的主要涉及如下4个方法:
方法|说明
|:——–:|:———:|
lock() |获取对此通道的文件的独占锁定。
lock(long position, long size, boolean shared) |获取此通道的文件给定区域上的锁定。
tryLock() throws IOException | 试图获取对此通道的文件的独占锁定。
tryLock(long position, long size, boolean shared) throws IOException | 试图获取对此通道的文件给定区域的锁定。
无|lock()等同于lock(0L, Long.MAX_VALUE, false)
无|tryLock()等同于tryLock(0L, Long.MAX_VALUE, false)
lock()和tryLock()的区别:
- lock()阻塞的方法,锁定范围可以随着文件的增大而增加。无参lock()默认为独占锁;有参lock(0L, Long.MAX_VALUE, true)为共享锁。
- tryLock()非阻塞,当未获得锁时,返回null。无参tryLock()默认为独占锁;有参tryLock(0L, Long.MAX_VALUE, true)为共享锁。
简单实例代码:
File file = new File("d:" + File.separator + "test.txt") ;
FileOutputStream output = null ;
FileChannel fout = null ;
try {
output = new FileOutputStream(file,true) ;
fout = output.getChannel() ;// 得到通道
FileLock lock = fout.tryLock() ; // 进行独占锁的操作
if(lock!=null){
System.