2013-04-09 42 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