JAVA :- 在 Linux 中不工作的多个 Java 应用程序之间的文件共享和锁定

Posted

技术标签:

【中文标题】JAVA :- 在 Linux 中不工作的多个 Java 应用程序之间的文件共享和锁定【英文标题】:JAVA :- File sharing and locking between multiple Java applications not working in Linux 【发布时间】:2020-11-04 03:04:14 【问题描述】:

我有两个独立的 Java 进程。说ABC和DEF。 DEF 是 ABC 的子级(也就是说,DEF 是由 ABC 生成的。ABC 和 DEF 都是分别使用两个 jar 文件 ABc.jar 和 DEF.jar 生成的)。我的要求是保留 ABC 和 DEF 通用的文件。该文件由 ABC 创建,将被锁定。 DEF 检查文件是否已解锁。如果解锁,则进程 DEF 退出。这是为了解决孤儿进程的问题,即父进程崩溃时子进程不会被杀死。

因此,在这种情况下,ABC 创建的文件将保持锁定状态,直到 ABC 退出。 DEF 已经在检查文件的锁是否被释放。由于释放锁的条件是 ABC 终止,所以只要 ABC 终止,DEF 就终止。

所以,我在ABC进程中创建了一个FileLock.java类:-

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileLock;

public class FileLock 

    public FileLockExample() throws FileNotFoundException 
        FileOutputStream fileOutStream;
        try 
            fileOutStream= new FileOutputStream("Temp.txt");
            FileLock fileLock ;
            try 
                fileLock = fileOutStream.getChannel().tryLock();
                if (fileLock != null) 
                    System.out.println("Locked File");
                    try 
                        Thread.sleep(1000);
                     catch (InterruptedException e) 
                        e.printStackTrace();
                    
                
             catch (IOException e) 
                e.printStackTrace();
            

         catch (FileNotFoundException e) 

            e.printStackTrace();
        

    

因此,一个文件 Temp.txt 被创建并被锁定。

现在我在 DEF 中添加了一个函数,用于检查文件是否被锁定。

public static void isFileUnlocked() 
        Integer count = 1000;
        boolean isFirstTry = false;
        while (count > 0) 
            try 
                if (!isFirstTry) 
                    FileOutputStream fos = new FileOutputStream("Temp.txt");
                    FileLock fileLock = fos.getChannel().tryLock();
                    isFirstTry = true;
                
                FileInputStream fis = new FileInputStream("Temp.txt");
                fis.read();
                System.exit(0);
             catch (IOException x) 

            
          Thread.sleep(1000);
          count--;
        
    

进程 DEF 中的函数 isFileUnlocked() 每隔一秒检查文件锁是否被释放。如果锁被释放,则说明 ABC 由于某些原因已经终止。因此,一旦文件锁被释放,DEF 就会退出。

我在 Windows 中验证了这一点,它似乎可以正常工作。然而,在 Linux 中,只要调用函数 isFileUnlocked(),进程 DEF 就存在。因此,当 DEF 尝试读取文件时,它能够这样做。 (这可能意味着文件已解锁)。

对此有什么想法吗?

【问题讨论】:

为什么不检查“DEF”程序中的锁? 【参考方案1】:

假设调用方法checkIfFileIsUnlocked()时[locked]文件没有关闭,并且假设您正在使用正确的参数调用方法checkIfFileIsUnlocked(),为了测试文件是否被锁定,您需要从文件。仅仅打开文件不会抛出异常。

这是一个写得很糟糕的例子,但它只是为了演示如何实现你的检查。


try 
    FileOutputStream fos = new FileOutputStream("lockfile.txt");
    FileLock fileLock = fos.getChannel().tryLock();

    FileInputStream fis = new FileInputStream("lockfile.txt");
    fis.read();

catch (IOException x) 
    x.printStackTrace();

上述代码运行时,下面一行抛出异常。

fis.read()

例外是:

java.io.IOException: The process cannot access the file because another process has locked a portion of the file

【讨论】:

在 Windows 中运行的相同代码在 Linux 中无法运行。在您分享的 sn-p 中,它在 Linux 中运行时从不进入 catch 块。 @Abhijith.M Linux 是否显示与 NIO 相同的问题,将上面的前 2 行交换为 FileChannel ch = FileChannel.open(p, StandardOpenOption.WRITE); FileLock fileLock = ch.tryLock(); @DuncG:感谢您的建议。你说的方法我试过了。它适用于 Windows,但不适用于 Linux。 @Abra:我已经修改了问题。你对为什么文件锁定机制在 Linux 中没有按预期工作有什么想法吗?

以上是关于JAVA :- 在 Linux 中不工作的多个 Java 应用程序之间的文件共享和锁定的主要内容,如果未能解决你的问题,请参考以下文章

python串口代码在windows中工作,但在linux中不工作

为啥通过 XOR 交换整数变量在一行中不起作用?

j_security_check 过滤器在 jboss eap 6.4 中不起作用

如何使 MySQL Connector/J 在 android 上工作?

Android模拟器显示在linux中不起作用

带有 keylisteners 的 Java swing gui 程序在 linux 中不起作用