【问题标题】:Thread won't output stream until it is terminated [duplicate]线程在终止之前不会输出流[重复]
【发布时间】:2019-06-27 19:06:31
【问题描述】:

我正在尝试通过运行外部 jar 打印实时输出,它在线程中运行并且 jar 确实被执行,问题是在线程终止之前不会打印输出。

public void run() {
    Process proc = null;
    try {

        proc = Runtime.getRuntime().exec("java -jar A.jar");    
        InputStream in = proc.getInputStream();
        InputStream err = proc.getErrorStream();

        BufferedInputStream bis = new BufferedInputStream(in);
        BufferedInputStream bes = new BufferedInputStream(err);

        String iss = IOUtils.toString(in, "UTF8");
        String ess = IOUtils.toString(err, "UTF8");

        System.out.println(iss);
        System.out.println(ess);

    } catch (IOException e) {
        e.printStackTrace();
        this.interrupt();
    }
}

【问题讨论】:

  • 在执行进程时,您需要单独的线程来读取两个流。
  • @SamuelPhilipp 谢谢!我会试试看。
  • 在这种情况下,您也不想使用IOUtils.toString(),因为它只会在流结束后返回。
  • 另外,IOUtils.toString() 会阻塞直到流结束。我认为你需要放弃IOUtils.toString(),甚至可能是BufferedInputStream,直接使用InputStream。
  • 另外,this.interrupt() 令人困惑,可能与问题无关。您可能希望删除这些细节以创建一个最小的示例。

标签: java multithreading


【解决方案1】:

您需要在单独的线程中运行它们,以便同时读取它们。

public void run() {
    try {
        Process proc = Runtime.getRuntime().exec("/home/martin/test.py");
        InputStream in = proc.getInputStream();
        InputStream err = proc.getErrorStream();

        Thread tIn = new Thread(() -> {
            try {
                while (true) {
                    int ch;
                    ch = in.read();
                    if (ch < 0)
                        break;
                    System.out.print((char) ch);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        Thread tErr = new Thread(() -> {
            try {
                while (true) {
                    int ch;
                    ch = err.read();
                    if (ch < 0)
                        break;
                    System.err.print((char) ch);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        tIn.start();
        tErr.start();

        try {
            tIn.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            tErr.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // this.interrupt();
    } catch (IOException e) {
        e.printStackTrace();
        // this.interrupt();
    }
}

这是一个单一功能的快速和肮脏的版本。当然,最好编写一个包装该功能的类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 2020-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多