【问题标题】:problem killing a process in a Java application在 Java 应用程序中杀死进程的问题
【发布时间】:2011-09-11 03:26:09
【问题描述】:

我创建了一个 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);

}

我想在窗口关闭时终止(杀死)已用 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*****    
  }

}

当窗口关闭时,不幸的是,进程没有被杀死......谁能给我一个解释和可能的解决方案?谢谢!!!

【问题讨论】:

    标签: java process


    【解决方案1】:

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

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

    查看您的代码后,我建议您以不同的方式工作: 在您的听众中,您正在破坏进程然后退出。因此,您可以将默认关闭操作设置为退出,然后在
    中执行进程销毁 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*****    
      }
    
    }
    

    【讨论】:

    • 感谢建议,但还是不行,进程还在运行中
    • 我提到的内容将使该方法被调用,以便destroy()首先被执行,因为它之前没有运行。但似乎您的 run.bat 文件正在启动其他进程,并且这些进程不会被您的进程上的 destroy() 破坏。检查以下帖子here
    【解决方案2】:

    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的children。

    【讨论】:

    • 这取决于 run.bat 的作用。如果bat文件启动了其他进程,则不会被终止。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    • 2020-05-11
    • 1970-01-01
    • 2011-09-15
    相关资源
    最近更新 更多