Java中的Process Builder和Process-如何在超时的情况下执行流程:?

Java中的Process Builder和Process-如何在超时的情况下执行流程:?,java,process,Java,Process,我需要在java中执行一个具有特定超时的外部批处理文件。这意味着,如果批处理执行的时间超过指定的超时时间,我需要取消执行 下面是我编写的示例代码: public static void main(String[] args) throws IOException, InterruptedException { ProcessBuilder p = new ProcessBuilder("c:\\wait.bat", "25"); // batch file execution will

我需要在java中执行一个具有特定超时的外部批处理文件。这意味着,如果批处理执行的时间超过指定的超时时间,我需要取消执行

下面是我编写的示例代码:

public static void main(String[] args) throws IOException, InterruptedException {
    ProcessBuilder p = new ProcessBuilder("c:\\wait.bat", "25");  // batch file execution will take 25 seconds.
    final long l = System.currentTimeMillis();
    System.out.println("starting..." + (System.currentTimeMillis() - l));
    final Process command = p.start();
    System.out.println("started..." + (System.currentTimeMillis() - l));

    Timer t = new Timer();
    t.schedule(new TimerTask() {

        @Override
        public void run() {
            command.destroy();
        }
    }, 5000);   // it will kill the process after 5 seconds (if it's not finished yet).
    int i = command.waitFor();
    t.cancel();
    System.out.println("done..." + (System.currentTimeMillis() - l));
    System.out.println("result : " + i);

    System.out.println("Really Done..." + (System.currentTimeMillis() - l));
}
批处理文件“wait.bat”如下所示:

@echo off
echo starting the process...
@ping 127.0.0.1 -n 2 -w 1000 > nul
@ping 127.0.0.1 -n %1% -w 1000> nul
echo process finished succesfully
@echo on
正如您在代码中看到的,批处理文件需要25秒才能完成(main方法中的第一行),计时器将在5秒后销毁该命令

下面是我的代码的输出:

starting...0
started...0
done...5000
result : 1
Really Done...5000
BUILD SUCCESSFUL (total time: 25 seconds)
正如您在输出中看到的,最后一行(“真的完成了…”)在第5秒执行,但应用程序在25秒后完成


我的问题是:即使我在计时器中调用了destroy方法,为什么jvm仍在等待进程完成

计时器的取消方法可能有问题。尝试以守护进程线程的形式启动计时器

Timer t = new Timer(true);
它是Java在Windows上的
进程.destroy()
实现中的一个重要部分。问题是批处理脚本(或其执行shell)被终止,但不会终止其自己的子进程(此处的ping)。因此,ping仍然在
.destroy()
之后运行,也在
.waitFor()
之后运行。但无论如何,虚拟机仍在等待ping完成后再完成自己

从Java方面看,似乎没有什么可以真正可靠地杀死ping

您可以考虑使用
start
(在批处理脚本中或外部)作为单独的过程调用ping

(另请参见此。)


或者更改为类似unix的操作系统。

如果使用unix/Linux,则编写一个wrapper bash shell脚本,通过超时中断外部命令,然后从Java调用该wrapper

包装器脚本如下所示

#!/bin/bash
timeout 60 <your command>
#/bin/bash
超时60
您可以通过检查脚本退出代码来检测超时是否已过期,如果超时,该代码为124

人工超时


这种“构建成功”从何而来between@Suraj:其netbeans默认消息将在应用程序终止后显示。我知道这是一个很老的对话,但process.destroy()与JDK 1.7.0_51配合使用。不,这不是原因,仍然是相同的结果。如果要终止它,请尝试将CTRL+C作为进程参数发送