2010-12-16 90 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。