2010-11-09 129 views
1

我開發了一個JSP Web應用程序,它根據每個請求生成一個新的Java線程。在每個新產生的線程中,我使用Runtime.exec()創建一個Process,並將進程對象存儲在線程中的一個實例變量中。我有一個要求,我必須殺死創建的子進程,並停止線程。所以,我重寫了線程中的中斷方法,以及在實例變量中已存儲的Process對象上調用destroy()的重寫方法。以下是代碼:殺死從線程啓動的Java進程

public class MyThread extends Thread { 
    private Process subprocess; 

    @Override 
    public void run() { 
     subprocess = Runtime.getRuntime().exec("myprocess.exe"); 
     subprocess.waitFor(); 
     /* 
      Some more statements 
     */ 
    } 

    @Override 
    public void interrupt() { 
     if(subprocess!=null) { 
      System.out.println("Destroying Process"); 
      subprocess.destroy(); 
     } 
     super.interrupt(); 
    } 
} 

重寫中斷方法是否合法? 在我中斷創建它的線程之前,我殺死創建的進程非常重要。我看到線程確實被中斷,因爲waitFor()之後的語句沒有得到執行。但是,銷燬()不起作用(但被調用)並且創建的「myprocess.exe」完成執行,即使在完成之前調用interrupt()方法。有人能幫我解決這個問題嗎?我錯過了什麼?

在此先感謝

回答

5

這不是非法覆蓋interrupt,但我不會推薦它。也許一個更清潔的方式來做到這一點是:

public class MyThread extends Thread { 
    private Process subprocess; 

    @Override 
    public void run() { 
     subprocess = Runtime.getRuntime().exec("myprocess.exe"); 
     try { 
      subprocess.waitFor(); 
     } 
     catch (InterruptedException e) { 
      subprocess.destroy(); 
     } 
     /* 
      Some more statements 
     */ 
    } 
} 

不要忘了,你也應該從子輸出/錯誤流中提取數據,否則你可能會風與全緩衝和封子。從這些數據流中讀取並丟棄數據即可。我懷疑commons-io軟件包有一些工具可以使它成爲單行文本,否則這是一個非常簡單的編寫自己的方法。

+0

這對我工作卡梅隆,非常感謝! – 2010-11-09 15:32:25

+0

但isnt只有在線程處於阻塞等待狀態時調用interrupt()方法時才拋出InterruptedException?當線程正忙於等待時它是否也被拋出?像在for或while循環中一樣? – 2010-11-09 15:34:11

+0

如果你正在等待,那麼你需要自己測試'Thread.interrupted()'。但爲什麼你會忙 - 等待?產生一些守護進程線程,每個線程只讀取一個'InputStream'到EOF,然後死亡。一個用於'subprocess.getInputStream()',一個用於'subprocess.getErrorStream()'。 – Jonathan 2010-11-09 15:48:02