java 文件锁[通俗易懂]

java 文件锁[通俗易懂]今天在分析HDFS数据节点的源码时,了解到在数据节点的文件结构中,当数据节点运行时,${dfs.data.dir}下会有一个名为”in_use.lock”的文件,该文件就是文件锁。文件加锁是JDK1.4引入的一种机制,它允许我们同步访问某个作为共享资源的文件。竞争同一文件的两个线程可能在不同的Java虚拟机上,或者一个是Java线程,另一个是操作系统中的某个本地线程。文件锁对其他的操作系

大家好,又见面了,我是你们的朋友全栈君。

今天在分析HDFS数据节点的源码时,了解到在数据节点的文件结构中,当数据节点运行时,${dfs.data.dir}下会有一个名为”in_use.lock”的文件,该文件就是文件锁。

文件加锁是 JDK1.4 引入的一种机制,它允许我们同步访问某个作为共享资源的文件。竞争同一文件的两个线程可能在不同的 Java 虚拟机上,或者一个是 Java 线程,另一个是操作系统中的某个本地线程。文件锁对其他的操作系统进程是可见的,因为 Java 的文件加锁直接映射到了本地操作系统的加锁工具(通过文件进行加锁)。

在javaNIO中提供了文件锁的功能,这样当一个线程获取文件锁后,才可以操作文件,其他线程是无法操作文件的,要想进行文件锁定的操作,则要使用FileLock类完成,此类的对象需要依靠FileChannel进行实例化。

java文件锁要么独占,要么共享。
共享锁:允许多个线程对文件进行读操作。
独占锁:只允许一个线程进行文件的读写操作

Trylock 与 lock 方法
tryLock(position,size,isShare); 第三个参数为 true 时为共享锁
tryLock() 是非阻塞式的,它设法获取锁,但如果不能获得,例如因为其他一些进程已经持有相同的锁,而且不共享时,抛出文件重叠锁异常【OverlappingFileLockException】。

lock() 是阻塞式的,它要阻塞进程直到锁可以获得,或调用 lock() 的线程中断,或调用 lock() 的通道关闭。

OverlappingFileLockException
单个 Java 虚拟机在某个特定文件上所保持的锁定、不同 jvm 或者不同操作系统获取同一文件锁时,先拿到的获得锁,后获取的抛出文件重叠锁异常【OverlappingFileLockException】。以上是 windows 才会出现如此现象,如果是linux会抛出异常:【java.io.IOException: Permission denied 】

测试代码如下:

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.OverlappingFileLockException;


public class StorageDirectory { 
   
    public static final String STORAGE_FILE_LOCK = "in_use.lock" ;
    File root ; //root directory 
    java.nio.channels.FileLock lock ; //storage lock
    /** * Lock storage to provide exclusive access. * * <p> if locking is supported we guarantee exculsive access to the * storage directory . Otherwise, no guarantee is given * * @throws Exception if locking file */
    public StorageDirectory(File dir){
        this.root = dir ;
    }
    public void lock() throws Exception{
        this.lock = tryLock() ;
        if(lock == null){
            String msg = "Cannot lock storage" + this.root + ". The directory is already locked." ;
            System.err.println(msg) ;
            throw new IOException(msg) ;
        }
    }

    public void unlock() throws IOException{
        if(this.lock == null)
            return ;
        this.lock.release() ;
        lock.channel().close() ;
        lock = null ;
    }
    /** * Attempts to acquire an exclusive lock on the storage * @return A lock object representing the newly-acquired lock or null if * storage is already lockd . * @throws IOException */
    java.nio.channels.FileLock tryLock() throws IOException{
        boolean deletionHookAdded = false ;
        File lockF = new File(root,STORAGE_FILE_LOCK) ;

        //如果没有文件
        if(!lockF.exists()){
            lockF.deleteOnExit() ;
            deletionHookAdded = true ;
        }

        RandomAccessFile file = new RandomAccessFile(lockF,"rws") ;
        java.nio.channels.FileLock res = null ;
        try{
            res = file.getChannel().tryLock() ;
        }catch(OverlappingFileLockException oe){
            file.close() ;
            return null ;
        }catch(IOException e){
            System.err.println("Cannot create lock on " + lockF) ;
            file.close() ;
            throw e ;
        }

        if(res !=null && !deletionHookAdded){
            //if the file existed prior to our startup, we didn't
            //call deleteOnExit above. But since we successfully locked
            //the dir , we can take care of cleaning it up 
            lockF.deleteOnExit() ;
        }
        return res ;
    }

}

测试类

import java.io.File;
import java.io.IOException;


class Operation implements Runnable{
    private StorageDirectory sd ;
    public Operation(StorageDirectory sd){
        this.sd = sd ;
    }
    public void run() {
        try {
            System.out.println("文件加锁");
            sd.lock() ;
        } catch (Exception e) {
            System.out.println("文件加锁失败") ;
            return ;
        }
        try {
            Thread.currentThread().sleep(1000) ;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            try {
                System.out.println("释放文件锁");
                sd.unlock() ;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}

public class Main { 
   

    /** * @param args */
    public static void main(String[] args) throws Exception{
        File dir = new File("G:\\eclipse-SDK-4.2.2-win32-x86_64\\workspace\\FileLock") ;
        StorageDirectory sd1 = new StorageDirectory(dir) ;
        new Thread(new Operation(sd1)).start() ;
    // Thread.sleep(2000) ;//注释掉文件加锁失败,解开注释文件加锁成功
        StorageDirectory sd2 = new StorageDirectory(dir) ;
        new Thread(new Operation(sd2)).start() ;
    }

}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/153487.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • idea2021.2.3激活码 3月最新注册码

    idea2021.2.3激活码 3月最新注册码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月15日
    166
  • cad快速选择命令快捷键_CAD快捷键,命令大全

    cad快速选择命令快捷键_CAD快捷键,命令大全一 常用 CTRL ALT 快捷键 ALT TK 如快速选择 ALT NL 线性标注 ALT VV4 快速创建四个窗口 ALT MUP 提取轮廓 Ctrl B 栅格捕捉模式控制 F9 Ctrl C 将选择的对象复制到剪切板上 Ctrl F 控制是否实现对象自动捕捉 F3 Ctrl G 栅格显示模式控制 F7 Ctrl J 重复执行上一步命令 Ctrl K 超级链接 Ctrl N 新建图形文件 C

    2025年9月6日
    11
  • Pytorch搭建DenseNet[通俗易懂]

    Pytorch搭建DenseNet[通俗易懂]文章目录DenseNet与ResNeXtDenseNet网络的搭建Growth_rateTransitionLayerBottleneck定义网络小测试问题1训练与测试可视化网络结构DenseNet与ResNeXt首先回顾一下DenseNet的结构,DenseNet的每一层都都与前面层相连,实现了特征重用。下图表示一个DenseBlock如图所示,在一个DenseBlock中,第i层的…

    2022年9月29日
    2
  • excel列中相同字符串统计_输入一串字符统计出现次数

    excel列中相同字符串统计_输入一串字符统计出现次数https://jingyan.baidu.com/article/6d704a132ea17328da51ca78.html通过excel快速统计一列中相同字符的个数,如果很少,你可以一个一个数、

    2022年8月1日
    3
  • java数据库系统开发案例精选_Java解析db文件

    java数据库系统开发案例精选_Java解析db文件JAVADB数据库范例关于javaDB的介绍就不说了,直接上例子。首先将derby.jar添加到classpath下面(IDE的话直接引入)importjava.sql.*;importjava.util.*;importjava.io.*;publicclassTest{publicstaticvoidmain(String[]args)throwsException{DB…

    2025年7月31日
    2
  • python基础教程 入门教程_python基础入门教程

    python基础教程 入门教程_python基础入门教程首先,我已经假定你已经看了无数遍的垃圾文章,然后依然搞不懂类和对象,但是呢起码知道有类和对象这么两个玩意儿。由于你没有编程经验,所以无法从学过的编程语言里通过类比去理解Python的‘类和对象’。咱们用生活中的例子来说说,建房子。类(class):相当于施工图纸(blueprint)对象(object):房子(已经建造好的)假设你手上有施工图纸(Blueprint),里面有房子的所有信…

    2022年8月29日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号