杀死Java应用程序中的进程的问题

时间:2011-09-10 17:23:07

标签: java process

我创建了一个Java应用程序,其中main方法(程序的开始)启动一个Process对象和MainWindow类的一个对象,该对象创建一个JFrame。

public static void main(String[] args) throws Exception {

File file = new File("./access/run.bat"); 
ProcessBuilder process_builder = new ProcessBuilder("cmd", "/c", file.getName());
process_builder.directory(file.getParentFile());
Process process = process_builder.start();
MainWindow window = new MainWindow(process);

}

当窗口关闭时,我想终止(kill)已经用 process.destroy()实例化的进程。以下是MainWindow类的一些代码:

public MainWindow(final Process process) throws TransformerException, ParserConfigurationException, Exception{  

JFrame mainWindowFrame = new JFrame();

*****some code here*****        

mainWindowFrame.addWindowListener(new WindowListener() {

public void windowClosed(WindowEvent arg0) {

    process.destroy();
    System.exit(0);
    }

*****some code here*****    
  }

}

当窗口关闭时,不幸的是,这个过程没有被杀死......有人可以给我一个解释吗?一个可能的解决方案?感谢!!!

2 个答案:

答案 0 :(得分:1)

根据文档here,只有在窗口被释放时才会调用windowClosed。为此,您可以在窗口上调用dispose或设置默认的关闭操作:在代码中,在创建JFrame之后,添加以下内容:

mainWindowFrame.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);

在查看您的代码后,我建议您采用不同的方式: 在你的听众中,你正在摧毁这个过程,然后退出。因此,你可以设置deafualt关闭操作退出然后执行中断的过程 实现 windowClosing 方法:将MainWindow的代码修改为以下内容:

public MainWindow(final Process process) throws TransformerException, ParserConfigurationException, Exception{  

JFrame mainWindowFrame = new JFrame();
mainWindowFrame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);

*****some code here*****        

mainWindowFrame.addWindowListener(new WindowListener() {

public void windowClosing(WindowEvent arg0) {

    process.destroy();

    }

*****some code here*****    
  }

}

答案 1 :(得分:0)

Process班的Javadoc说:

 The subprocess is not killed when there are no more references 
 to the Process object, but rather the subprocess 
 continues executing asynchronously.

There is no requirement that a process represented 
by a Process object execute asynchronously or concurrently 
with respect to the Java process that owns the Process object.

在互联网上搜索后,从Java 1.3开始,它似乎是Java平台中的issue。我发现这个blog entry解释了Java中Process的许多问题。

问题是process在杀死应用程序后成为孤儿。在您的代码中,您将从GUI中删除Process,因为GUI(MainWindow类)具有自己的线程,而不是Process父级。这是父母/孩子的问题。 有两种方法可以解决这个问题:

  1. 由于主线程是父进程,因此主线程必须调用destroy方法。因此,您必须保留对process对象的引用。

  2. 第二种方法是在启动MainWindow时创建流程。在MainWindow类的参数中,您可以传递进程的参数。因此,当调用windowClosed方法时,如果MainWindow关闭,Process将被销毁,因为后者是MainWindow的子节点。