如果超过分配的时间,如何杀死进程

时间:2013-04-09 10:28:57

标签: java multithreading timeout runnable

我想知道如果一个进程超过预定义的时间,检测/终止进程的最佳方法是什么。我知道一种古老的方法是使用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 个答案:

答案 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。有两个主要类别: