2010-12-16 86 views
1

我有一個擴展線程的類,當它啓動時,它運行一個jar的Main方法。當我終止線程時,它不會終止它啓動的進程。我該如何解決這個問題?謝謝!終止一個線程運行一個罐子

下面是從我的自定義Thread類的run()方法。

@Override 
    public void run() { 
     if(parent != null) { 
      MessageConsole console = new MessageConsole(parent.getConsole().getTextPane()); 
      console.redirectOut(new Color(240, 240, 240), null); 
      console.redirectErr(Color.RED, null); 
      console.setMessageLines(20); 
     } 
     if(oParent != null) { 
      MessageConsole console = new MessageConsole(oParent.getConsole().getTextPane()); 
      console.redirectOut(new Color(240, 240, 240), null); 
      console.redirectErr(Color.RED, null); 
      console.setMessageLines(20); 
     } 
     try { 
      somejar.SomeJar.main(args); 
     } catch (Exception ex) { 
      System.err.println("Engine failed to start!\nSuggestion: Restart the application, and if the issue is not fixed reinstall the application."); 
     } 
    } 

回答

3

當我終止線程時,它不會終止它啓動的進程。我該如何解決這個問題?

沒有可靠的方法來做到這一點。

首先,沒有可靠的方法來終止線程。 嘗試的首選方法是在線程上調用Thread.interrupt(),但這可能會被忽略。如果您致電已棄用方法Thread.stop(),則可能會導致JVM不穩定。

其次,即使假設您終止了JAR線程,也無法可靠地終止它創建的任何子線程。您無法可靠地將子線程與應用程序其他部分創建的其他線程區分開來。如果你能識別它們,你不能可靠地殺死它們。

最好的辦法是啓動一個新的JVM作爲運行JAR的外部進程。在正常情況下,JVM可以可靠地終止它創建的外部進程。 (也有例外,例如setuid命令,但這裏不應該是個問題。)

+0

@Stephen C,同意這是最好的解決方案。如果它不是一個選項,則可以嘗試識別子線程的一種方法是在新的ThreadGroup中啓動第一個線程,默認情況下,子項將在同一組中啓動。它不可靠,但可能比沒有好。 – 2010-12-16 22:27:17

+0

@Peter Lawrey - 線程組太不可靠。例如,如果你依賴它們,你最終可能會殺死那些JAR線程沒有「擁有」的線程。這可能比沒有任何事情更糟糕。 – 2010-12-16 23:00:16

+0

有沒有一種方法可以通過所有的孩子來枚舉並殺死每一個?或者可能獲得每個線程的進程ID並單獨終止它們? – Jakir00 2010-12-16 23:02:55

0

如果不終止進程,則無法終止線程。

您可以發信號通知它停止interrupt()或拋出一個異常,但讓它停止的唯一方法是從run()方法返回或拋出一個Throwable。