只要主程序执行

时间:2017-12-04 20:57:51

标签: java multithreading apache-commons

我在这里要完成的是通过Apache Commons Exec实例化第二个.jar的实例,而不是抛出第二个Java程序的主实例。

第二个.jar的作用基本上是将字节发送到stdout。这是启动此程序的代码。

private void runJar(PipedOutputStream output) throws IOException {
    DefaultExecutor executor = new DefaultExecutor();

    CommandLine commandLine;
    String executeMe = "java -jar myjar.jar";
    commandLine = CommandLine.parse(executeMe);

    executor.setStreamHandler(new PumpStreamHandler(output, null));
    executor.execute(commandLine, new DefaultExecuteResultHandler());
}

但到目前为止,我找不到一种方法来执行此操作而不阻止正常程序与库的正常流程,所以我作为一种解决方法做的是创建Thread,就像这样...

Thread t3 = new Thread() {
    public void run() {
        try {
            runJar(output);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
};
t3.start();

我尝试通过cmd启动命令,一切正常,但在这种情况下,当我在Java中运行所有内容时,线程似乎在几秒钟后停止。

当我创建一个新线程时,我是否遗漏了某些内容,因此只要主程序可以存在,

更新

来自第一个.jar的可运行示例可以是此代码......

public class SecondApp {

public static void main(String[] args) throws ClassNotFoundException, IOException, InterruptedException {
            File in = new File(args[0]);
    try (InputStream input = new FileInputStream(in)) {
        int bytesRead, CHUNK_SIZE = 4096;
        byte[] data = new byte[CHUNK_SIZE];

        while (true) {
            bytesRead = input.read(data, 0, CHUNK_SIZE);
                            if (bytesRead > 0) {
                                System.out.write(data, 0, bytesRead);
                                System.out.flush();
                            } else if (bytesRead == -1) {
                                System.exit(0);
                            }
        }

    }
}

它基本上向stdout吐出字节。第三个应用程序只是一个外部应用程序(ffmpeg),它通过PipedInputStream从第二个.jar接收这些字节,就像这样......

PipedOutputStream output = new PipedOutputStream();
PipedInputStream input = new PipedInputStream();
output.connect(input);

为了成功调试和了解Thread状态,我已经改变了同步的异步执行,现在我得到两个线程都处于RUNNABLE状态并且是ALIVE。

@Override
public void run() {
        try {
            DefaultExecutor executor = new DefaultExecutor();

            CommandLine commandLine;
            String executeMe = "java -jar myjar.jar";
            commandLine = CommandLine.parse(executeMe);

            executor.setStreamHandler(new PumpStreamHandler(output, null));
            executor.execute(commandLine); //, new DefaultExecuteResultHandler());
        } catch (ExecuteException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
}

正如@matt所说,可能是FFMPEG线程的输出没有被消耗的问题。

            executor.setStreamHandler(
                new PumpStreamHandler(
                        null, // stdout
                        null, // stderr
                        input)); // stdin

这是FFMPEG执行程序的前一行,现在由NullOutputStream(来自Apache Commons Exec的那个)更改。

            executor.setStreamHandler(
                new PumpStreamHandler(
                        new NullOutputStream(), // stdout
                        null, // stder
                        input)); // stdin

在这些更改之后,流似乎在几秒后停止,因此可能是@matt说的原因,流没有被消耗并且已经满了。为什么不使用NullOutputStream()?

0 个答案:

没有答案