Java中的进程间文件锁定

Posted

技术标签:

【中文标题】Java中的进程间文件锁定【英文标题】:Inter-process file locking in Java 【发布时间】:2018-02-15 22:52:08 【问题描述】:

我没有找到任何具体的东西,只有像这样的线程 that,没有显示实现。

我需要创建一个在两个或多个进程(不是线程!)之间共享的文件锁。我需要在一个进程中读/写文件,并保证没有其他进程同时写入文件。 FileChannel.lock() 不能完成这项工作,因为只要存在锁,它就会抛出异常(OverlappingFileLockException)。

我有两个想法如何实现进程间互斥锁,但对我来说似乎都有点不好。

    重复锁定操作直到它起作用 - 很恶心,但很简单,我猜它应该起作用吗?

    RandomAccessFile rFile = new RandomAccessFile(file, "rw");
    FileChannel channel = rFile.getChannel();
    FileLock lock;
    boolean locked = false;
    while(!locked) 
        try 
            lock = channel.lock();
            locked = true;
         catch(OverlappingFileLockException e) 
            Thread.sleep(10);
        
    
    lock.release();
    

    每当抛出异常时,将当前进程转换为服务器。使用 ServerSocket 来监听其他进程,并使用 Socket 来传达 lock.release() 已被调用。这对我来说听起来像是用大炮杀死苍蝇。

这两种处理我的问题的正确方法是否正确?或者是否已经存在允许跨进程锁定文件的 Java 机制?

【问题讨论】:

你想让两个进程锁定同一个文件? 是:1 个文件,锁定的顺序并不重要。我只是想确保2个进程不能同时访问该文件。 为什么抛出异常是个问题? while (true) try lock file; do your thing; unlock file; return; catch don't care; maybe wait a sec though 我似乎记得JVM指定文件锁定可能不会成功并且取决于平台。只能保证在 JVM 内锁定,不能保证与另一个进程锁定。即,您的代码可能不可移植,因此请务必在每个平台上进行测试。 这可以解释为什么它没有内置的Java机制。我会确保在我感兴趣的平台上进行测试。 【参考方案1】:
try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) 
    while (raf.getChannel().tryLock() == null) 
        Thread.sleep(10);
    
    // lock acquired

try-with-resurces 块将自动释放锁(间接 - 通过关闭 RandomAccessFile)。 顺便说一句,OverlappingFileLockException 被抛出是因为当前 JVM 已经拥有锁,或者当前 JVM 的线程已经在等待它。

【讨论】:

以上是关于Java中的进程间文件锁定的主要内容,如果未能解决你的问题,请参考以下文章

c++ - 互斥锁或群 fcntl.h 锁定只写操作

PHP进程锁

SylixOS文件记录锁使用

释放文件锁时如何通知另一个进程?

共享内存锁定和进程崩溃

拆分 MS Access 数据库需要很长时间才能打开 - 后端不断锁定和解锁