Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 读取为写入而锁定的文件_Java_Locking - Fatal编程技术网

Java 读取为写入而锁定的文件

Java 读取为写入而锁定的文件,java,locking,Java,Locking,我使用文件锁定作为防止多次执行我的应用程序的手段: FileLock lock = fc.tryLock(); if (lock == null) { System.out.println("Error: The process is already running."); } 到目前为止还不错。现在我想写另一个进程,可以杀死第一个进程。 我想在锁文件中写入当前PID。第二个进程将验证锁是否在这里(意味着进程正在运行),读取文件并终止PID。读取前验证锁是强制性的,因为操作系统可能会回

我使用文件锁定作为防止多次执行我的应用程序的手段:

FileLock lock = fc.tryLock();
if (lock == null) {
    System.out.println("Error: The process is already running.");
}
到目前为止还不错。现在我想写另一个进程,可以杀死第一个进程。 我想在锁文件中写入当前PID。第二个进程将验证锁是否在这里(意味着进程正在运行),读取文件并终止PID。读取前验证锁是强制性的,因为操作系统可能会回收PID:主进程可能会停止,其PID会被另一个进程重用。问题是读取文件是不可能的,因为锁(而我认为锁只会阻止写入…)

下面是一个简化的代码:

public class TestLock {

    public static void main(String[] args) throws Exception {
        if (args.length == 1 && "kill".equals(args[0])) {
            kill();
        } else {
            run();
        }
    }

    private static void run() throws Exception {
        File file = new File("test.lock");
        try (FileOutputStream fos = new FileOutputStream(file)) {
            FileLock lock = fos.getChannel().tryLock();
            if (lock == null) {
                System.err.println("Error: The process is already running.");
            } else {
                int pid = Integer.parseInt(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);
                System.out.println("Process is launched with PID = " + pid);
                fos.write(String.valueOf(pid).getBytes("UTF-8"));
                while(true) {
                    Thread.sleep(3000);
                    System.out.println("App is running");
                }
            }
        }
    }

    private static void kill() throws Exception {
        File file = new File("test.lock");
        if (!file.exists()) {
            System.err.println("Error: The process is not running.");
            return;
        }
        try (FileChannel fc = FileChannel.open(file.toPath(), StandardOpenOption.READ)) {
            FileLock lock = fc.tryLock(0L, Long.MAX_VALUE, true);
            if (lock == null) {
                ByteBuffer bb = ByteBuffer.allocate(20);
                fc.read(bb);
                String pid = new String(bb.array(), "UTF-8").trim();
                System.out.println(pid);
                // Kill the process
            } else {
                System.err.println("Error: The process is not running.");
            }
        }
    }
}
如果我在没有参数的情况下运行应用程序两次,第二个实例将显示“错误:进程已在运行”。如果我尝试在进程未运行时终止进程,则会得到“错误:进程未运行”。但如果我尝试终止正在运行的进程,则会得到IOException“该进程无法访问该文件,因为另一个进程已锁定该文件的一部分”

在其他线程中看到锁只是建议性的(如果我理解正确的话,如果没有检查就不会真正锁定),我尝试删除锁检查并在kill方法中使用一个简单的文件读取器,但我得到了相同的错误。(无论如何,我宁愿不这样做,因为PID重用,如前所述)