java - 在java中,如何让单个线程等待进程完成?

标签 java multithreading process wait

这是我所拥有的: 我有一个启动进程的线程,该进程由 ProcessBuilder 创建并在终端中启动字符串命令。有许多并发线程执行相同的操作,但处理不同的数据。

这是我想做的: 我想创建一个线程(启动一个进程)来等待该进程直到它完成。我想出了两种方法,但都不起作用。

方法一:使用process.waitFor();这会导致所有并发线程等待一个进程(通常是第一个进程)完成。 waitFor() 的说明;说它让单个线程等待,但这不是它所做的,它实际上让所有线程等待。因此该程序不再并发。

方法 2:运行另一个线程,从该进程中读取管道流,等待直到有流,然后运行应该在该进程之后运行的函数。缺点是现在有很多线程,所以我不喜欢使用这种方法。此方法的另一个问题是我对应该使用流程的哪些属性感到困惑?输出流、输入流还是错误流?

这是代码:

public class Thread1 extends Thread{
private String[] incommand;    //this is the command for the process builder
private String newoutputfile;
InputStream ins = null;
Reader r = null;
BufferedReader br = null;
ProcessBuilder pbtx = null;

public Thread1(String[] incommand, String newoutputfile){
    super("Thread1");
    this.incommand = incommand;        
    this.newoutputfile = newoutputfile;
    this.pbtx = new ProcessBuilder();
}
@Override
public void run(){
    try{                    
                pbtx.command(incommand);                                     
                Process ptx = pbtx.start();
                //to make sure job is done
                ptx.waitFor(); //problem is apparently here
                // made sure job is done
                //the next function is supposed to run after the process is finished                
                    rite();                    
                //
            } catch (IOException ex){
                System.out.println("exception in thread t1");
                ex.printStackTrace();
            }
            catch (InterruptedException yo){
            System.out.println("exception in thread t1");
            }
            }

顺便说一下,该进程是一个 ffmpeg 进程,每个进程都处理不同的视频数据(没有数据依赖性或竞争条件或此处的任何内容)。所有这些 thread1 线程都是由另一个函数(main)中的另一个主线程创建和启动的。操作系统为Linux。 IDE 是 Netbeans(这是我获取每个功能的描述的地方)。我尝试使复制粘贴的代码尽可能短(为了简单起见),因此,如果您认为需要其他功能的代码或程序的其余部分,请通知我将它们粘贴到此处。

非常感谢,

最佳答案

我相信您确实需要使用单独的线程来读取输入;我没有找到避免它的方法。我使用以下算法( in the H2 database ),它对我来说效果很好。另请注意redirectErrorStream:

ProcessBuilder pb = new ProcessBuilder();
pb.command(cmd.array());
pb.redirectErrorStream(true);
Process p = pb.start();
copyInThread(p.getInputStream(), quiet ? null : sysOut);
p.waitFor();
return p.exitValue();

private static void copyInThread(final InputStream in, final OutputStream out) {
    new Thread() {
        @Override
        public void run() {
            try {
                while (true) {
                    int x = in.read();
                    if (x < 0) {
                        return;
                    }
                    if (out != null) {
                        out.write(x);
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    } .start();
}

关于java - 在java中,如何让单个线程等待进程完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21453217/

相关文章:

java - 接受任意次数的输入

java - arr.equals(anotherArr) 和 arr == anotherArr 有区别吗?

java - 在开始另一个方法之前等待方法完成的简单方法

TFS 不加载自定义程序集

c - 为什么 MPI_SEND 在我的 for 循环中不起作用?如果明确说明,它可以正常工作

使用 https 和 pem 证书的 Java 客户端

Java XML JDOM2 XPath - 使用 XPath 表达式从 XML 属性和元素读取文本值

c++ - std::thread 未定义行为

c++ - 导致C++ 11 std::mutex将阻塞的线程锁定为被动等待状态?

python - 使用 python 在任务管理器中杀死 matlab 进程