0

我有一个 java 类,目前通过以下方式启动 aa 脚本

Process proc = Runtime.getRuntime().exec(" run my script");

由于特定原因,这几乎一直在运行。如果脚本由于某种原因而死掉,java 类只会重新启动它。

现在我需要偶尔杀死这个过程。所以我决定启动一个线程,它只会坐下来等待特定的时间,然后终止该进程。java主类或其他类仍然会看到进程死亡,然后重新启动它。

我不知道如何让这个线程看到进程并随后经常杀死它。关于如何创建该线程的任何建议?作为说明,我有一段时间不用处理线程了,所以我有点生疏了。

我的类的简单伪代码,以了解我在做什么的基本概念:

Class MyClass{

    Process mProc;

    main(args){
        do{
            try{
                mProc = Runtime.getRuntime().exec("cmd /C myScript");
                mProc.destroy();
            } catch(Exception e){
                Log(e);
            }
        } while(true);
4

1 回答 1

1

我不知道如何让这个线程看到进程并随后经常杀死它。

从 Java 6 开始,目前这并不容易做到。Process该类有一个waitFor()方法,但它不需要超时,这很悲惨,因为它在内部只是在调用wait()——至少在UnixProcess.

你可以做的,这有点像一个黑客,是同步Process并调用wait(timeoutMillis)你自己。就像是:

Process proc = new ProcessBuilder().command(commandArgs).start();
long startMillis = System.currentTimeMillis();
synchronized (proc) {
    proc.wait(someTimeoutMillis);
}
long diff = System.currentTimeMillis() - startMillis;
// if we get here without being interrupted and the delay time is more than
// someTimeoutMillis, then the process should still be running
if (diff >= someTimeoutMillis) {
   proc.destroy();
}

问题是存在竞争条件,如果该过程在您同步之前proc完成,您将永远等待。另一种解决方案是proc.waitFor()在一个线程中执行,然后在超时到期后在另一个线程中中断它。

Process proc = new ProcessBuilder().command(commandArgs).start();
try {
   // this will be interrupted by another thread
   int errorCode = proc.waitFor();
} catch (InterruptedException e) {
   // always a good pattern to re-interrupt the thread
   Thread.currentThread().interrupt();
   // our timeout must have expired so we need to kill the process
   proc.destroy();
}
// maybe stop the timeout thread here

另一种选择是使用proc.exitValue()允许您测试进程是否已执行的选项。不幸的是,如果它还没有完成,而不是返回-1或抛出的东西。IllegalThreadStateException

于 2013-05-09T14:54:24.250 回答