2013-04-09 53 views
1

我想知道如果超过预定义的时间,检测/终止一个进程的最好方法是什么。我知道一个古老的方法是使用ant包中的watchdog/timeoutobserver类。但是现在这已经被弃用了,所以我想知道现在应该怎么做?java - 如果一个进程超过了分配时间,如何杀死一个进程

这里是我的代码有一个使用看门狗:

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

发送一个中断到线程。 – Ankit 2013-04-09 10:33:21

+0

获得系统时间以毫秒为单位,经过你想要的时间后,调用finalize(); – 2013-04-09 10:35:18

+1

请清楚你的问题:你是在杀死一个“线程”还是一个“进程”? (从你的代码看来,它似乎是后者,但是你问的是误导) – 2013-04-09 10:42:58

回答

0

理论上主题有方法stop()是完全杀死线程。自java 1.1以来,此方法已弃用,因为它可能导致资源泄漏。所以,你真的不推荐使用它。

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

+0

从示例代码,我相信OP实际上是要求杀死进程而不是线程。 – 2013-04-09 10:39:00

0

如果您只关注WatchDog本身已被弃用,那么在一段时间后使用TimerTask并执行process.destroy()并不困难。

1

尝试

final Process p = ... 
    Thread t = new Thread() { 
     public void run() { 
      try { 
       Thread.sleep(1000); 
       p.destroy(); 
      } catch (InterruptedException e) { 
      } 
     }; 
    }; 
    p.waitFor(); 
    t.interrupt(); 
+0

这就是我期待的!但't.start();'忘记了。 – 2015-04-13 11:46:16