【问题标题】:Killing a Java Process started from a thread杀死从线程开始的 Java 进程
【发布时间】:2010-11-09 14:35:17
【问题描述】:

我开发了一个 JSP Web 应用程序,它在每个请求时都会生成一个新的 Java 线程。在每个新生成的线程中,我使用 Runtime.exec() 创建一个进程,并将进程对象存储在线程的实例变量中。我有一个要求,我必须杀死创建的子进程并停止线程。因此,我覆盖了线程中的中断方法,并且在覆盖的方法中,我在实例变量中已经存储的 Process 对象上调用了 destroy()。以下是代码:

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() 没有执行之后的语句。但是,destroy() 不起作用(但被调用)并且创建的“myprocess.exe”完成执行,即使我在完成之前调用了 interrupt() 方法。有人可以帮我解决这个问题吗?我错过了什么?

提前致谢

【问题讨论】:

    标签: java multithreading process interrupt


    【解决方案1】:

    覆盖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 包有工具可以使它成为单行,否则它是一个相当简单的方法来编写自己。

    【讨论】:

    • 但是只有在线程处于阻塞等待状态时调用interrupt()方法才抛出InterruptedException?当线程处于忙等待状态时也会抛出它吗?就像在 for 或 while 循环中一样?
    • 如果你正忙着等待,那么你需要自己测试Thread.interrupted()。但是你为什么要忙着等呢?产生几个守护线程,每个线程都只是读取一个InputStream 到 EOF,然后死掉。一种用于subprocess.getInputStream(),一种用于subprocess.getErrorStream()
    • InterruptedException 被捕获,但在 catch 块中,调用 destroy() 不会杀死子进程。但是,当我不从输入和错误流中提取消息时,子进程甚至都没有启动。知道为什么吗?
    • 这可能是子进程的问题,或者可能是 Windows 或 JVM 没有很好地实现进程终止(我假设你在 Windows 上,因为你的代码中有一个 .exe )。尝试开始一个不同的简单过程,看看会发生什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    相关资源
    最近更新 更多