我想知道如果一个进程超过预定义的时间,检测/终止进程的最佳方法是什么。我知道一种古老的方法是使用ant包中的watchdog / timeoutobserver类。但是现在已经弃用了,所以我想知道现在应该怎么做?
以下是我使用看门狗的代码:
import org.apache.tools.ant.util.Watchdog;
import org.apache.tools.ant.util.TimeoutObserver;
public class executer implements TimeoutObserver {
private int timeOut = 0;
Process process = null;
private boolean killedByTimeout =false;
public executer(int to) {
timeOut = t;
}
public String executeCommand() throws Exception {
Watchdog watchDog = null;
String templine = null;
StringBuffer outputTrace = new StringBuffer();
StringBuffer errorTrace = new StringBuffer();
Runtime runtime = Runtime.getRuntime();
try {
//instantiate a new watch dog to kill the process
//if exceeds beyond the time
watchDog = new Watchdog(getTimeout());
watchDog.addTimeoutObserver(this);
watchDog.start();
process = runtime.exec(command);
//... Code to do the execution .....
InputStream inputStream = process.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
bufferedReader = new BufferedReader(inputStreamReader);
while (((templine = bufferedReader.readLine()) != null) && (!processWasKilledByTimeout)) {
outputTrace.append(templine);
outputTrace.append("\n");
}
this.setStandardOut(outputTrace);
int returnCode = process.waitFor();
//Set the return code
this.setReturnCode(returnCode);
if (processWasKilledByTimeout) {
//As process was killed by timeout just throw an exception
throw new InterruptedException("Process was killed before the waitFor was reached.");
}
} finally {
// stop the watchdog as no longer needed.
if (aWatchDog != null) {
aWatchDog.stop();
}
try {
// close buffered readers etc
} catch Exception() {
}
//Destroy process
// Process.destroy() sends a SIGTERM to the process. The default action
// when SIGTERM is received is to terminate, but any process is free to
// ignore the signal or catch it and respond differently.
//
// Also, the process started by Java might have created additional
// processes that don't receive the signal at all.
if(process != null) {
process.destroy();
}
}
public void timeoutOccured(Watchdog arg0) {
killedByTimeout = true;
if (process != null){
process.destroy();
}
arg0.stop();
}
}
}
任何帮助都会非常感激,因为我有点失落。我正在尝试将其应用到Java 7中,但如果它超出分配时间,我就不会以最好的方式来杀死它。
谢谢,
答案 0 :(得分:1)
试
final Process p = ...
Thread t = new Thread() {
public void run() {
try {
Thread.sleep(1000);
p.destroy();
} catch (InterruptedException e) {
}
};
};
p.waitFor();
t.interrupt();
答案 1 :(得分:0)
理论上,Thread有方法stop()
完全杀死线程。自java 1.1以来,不推荐使用此方法,因为它可能会导致资源泄漏。因此,我们不建议您使用它。
“正确”的解决方案是实现您的线程,以便在收到特殊“信号”时可以正常退出。您可以使用“中断”机制:您的监视程序应该调用超过时间限制的线程的“interrupt()”。但是线程应该调用isInterrupted()
本身并在它被中断时退出。好消息是像sleep()
和wait()
这样的方法已经支持这个,所以如果你的线程正在等待并且你从外部中断它,它将被抛出InterruptedException
。
答案 2 :(得分:0)
如果您只是担心WatchDog
本身已被弃用,那么使用TimerTask
并在一段时间后执行process.destroy()
并不困难。
答案 3 :(得分:0)
我编写了一组ExecutorServices
,它们会在给定一段时间后执行取消进程。此代码已经检入GitHub。
用于创建ExecutorService
的类是CancelingExecutors。有两个主要类别:
Callable
Callables