1

我想知道如果进程超过预定义的时间,最好的方法是检测/杀死进程。我知道一种旧方法是使用 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,但如果它挂起超过分配的时间,我还没有掌握杀死它的最佳方法。

谢谢,

4

4 回答 4

1

尝试

    final Process p = ... 
    Thread t = new Thread() {
        public void run() {
            try {
                Thread.sleep(1000);
                p.destroy();
            } catch (InterruptedException e) {
            }
        };
    };
    p.waitFor();
    t.interrupt();
于 2013-04-09T10:55:31.037 回答
0

从理论上讲,线程具有stop()完全杀死线程的方法。从 java 1.1 开始不推荐使用此方法,因为它可能导致资源泄漏。所以,真的不建议你使用它。

“正确”的解决方案是实现您的线程,以便它们在收到特殊“信号”时可以优雅地退出。您可以使用“中断”机制:您的看门狗应该调用超过时间限制的线程的“interrupt()”。但是线程应该调用isInterrupted()自己并在被中断时退出。好消息是该方法喜欢sleep()并且wait()已经支持它,因此如果您的线程正在等待并且您从外部中断它,InterruptedException它将被抛出。

于 2013-04-09T10:35:14.807 回答
0

如果你只是关心WatchDog它本身被弃用了,那么你使用它并没有什么困难,过一段时间TimerTask再做。process.destroy()

于 2013-04-09T10:41:12.203 回答
0

我写了一组ExecutorServices在给定一段时间执行后将取消进程的方法。此代码已签入 GitHub。

用于创建的类ExecutorServiceCancelingExecutors。主要有两个类:

于 2013-04-09T10:42:32.127 回答