线程停止执行

时间:2016-06-28 07:56:04

标签: java multithreading io

我有一个在外部进程中运行shell脚本的Thread,我使用Apache的IOUtils来读取来自此外部进程的stderr和stdout流,如下所示:

Thread t = new Thread(()-> {
        ProcessBuilder pb =  new ProcessBuilder("sh");
        Process p = null;
        try {
            p = pb.start();
            OutputStream os = p.getOutputStream();
            os.write("sleep 30 ; echo test".getBytes());
            os.flush();
            os.close();
            InputStream is = p.getInputStream();
            InputStream es = p.getErrorStream();
            String stdout = IOUtils.toString(is,"UTF-8");
            String stderr = IOUtils.toString(es,"UTF-8");
            int retval = p.waitFor();
        } catch (Exception e) {
            System.out.println("Got exception: "+e.toString());
        } finally {
            System.out.println("Done now!");
        }
    });
t.start();
Thread.sleep(7000);
t.interrupt();

出于某种原因,当我运行此测试用例时,永远不会抛出异常(catch块永远不会运行),finally块永远不会运行。我有什么问题没有抓到吗?是否应该通过不同的线程收集stdout和stderr?

2 个答案:

答案 0 :(得分:3)

如果stderr的缓冲区填满你的程序将停止。除非你需要它们在不同的字符串中,否则我会将它们重定向到另一个字符串。

我会使用ProcessBuidler.redirectErrorStream来组合输出,因此您不需要额外的线程来阅读stderr

waitFor(long, TimeUnit)超时,因此您无需启动后台主题。

我建议你打印出你的stderr和stdout,这样你就可以看到它们,因为它们可能表明出了什么问题。

答案 1 :(得分:1)

看起来正确,除了线程在处理来自shell的任何输出之前被杀死(中断)的事实。问题是shell会休眠30秒,线程会在7秒内中断。

您可能无法看到来自catch或finally块的任何消息,这可能是因为{" shell"之前的main()方法退出程序。线程实际上已激活。