Java:如何使这个主线程等待新线程终止

时间:2022-10-14 20:58:01

I have a java class that creates a process, called child, using ProcessBuilder. The child process generates a lot of output that I am draining on a separate thread to keep the main thread from getting blocked. However, a little later on I need to wait for the output thread to complete/terminate before going on, and I'm not sure how to do that. I think that join() is the usual way to do this but I'm not sure how to do that in this case. Here is the relevant part of the java code.

我有一个java类,使用ProcessBuilder创建一个名为child的进程。子进程生成大量输出,我在一个单独的线程上耗尽,以防止主线程被阻塞。但是,稍后我需要等待输出线程完成/终止才能继续,我不知道该怎么做。我认为join()是通常的方法,但我不知道在这种情况下如何做到这一点。这是java代码的相关部分。

    // Capture output from process called child on a separate thread

    final StringBuffer outtext = new StringBuffer("");
    new Thread(new Runnable() {
        public void run() {
            InputStream in = null;
            in = child.getInputStream();
            try {
                if (in != null) {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                    String line = reader.readLine();
                    while ((line != null)) {
                        outtext.append(line).append("\n");
                        ServerFile.appendUserOpTextFile(userName, opname, outfile, line+"\n");
                        line = reader.readLine();
                    }
                }
            } catch (IOException iox) {
                throw new RuntimeException(iox);
            }
        }
    }).start();

    // Write input to for the child process on this main thread
    //
    String intext = ServerFile.readUserOpTextFile(userName, opname, infile);
    OutputStream out = child.getOutputStream();
    try {
        out.write(intext.getBytes());
        out.close();
    } catch (IOException iox) {
        throw new RuntimeException(iox);
    }

    //  ***HERE IS WHERE I NEED TO WAIT FOR THE THREAD TO FINISH ***

    // Other code goes here that needs to wait for outtext to get all
    // of the output from the process

    // Then, finally, when all the remaining code is finished, I return
    // the contents of outtext

    return outtext.toString();

3 个解决方案

#1


15  

You can join on that thread. You would get the instance of the thread and when needed to wait invoke its join method.

您可以加入该主题。您将获得该线程的实例,并在需要时等待调用其join方法。

 Thread th = new Thread(new Runnable() {  ... } );
 th.start();
 //do work 
 //when need to wait for it to finish
 th.join();
 //th has now finished

Others will suggest a CountdownLatch, CyclicBarrier or even a Future but I find this to be easiest to implement on a very low level.

其他人会建议使用CountdownLatch,CyclicBarrier甚至是Future,但我发现这是最容易在非常低的水平上实现的。

#2


3  

You have to assign your thread to a variable and later call join() on this variable.

您必须将线程分配给变量,然后在此变量上调用join()。

#3


3  

final StringBuffer outtext = new StringBuffer("");  
Thread outputDrainThread = new Thread(new Runnable() {
    public void run() {
        // ... 
    }
}).start();

// ...

//  ***HERE IS WHERE I NEED TO WAIT FOR THE THREAD TO FINISH ***
outputDrainThread.join();    

// ...
return outtext.toString();

#1


15  

You can join on that thread. You would get the instance of the thread and when needed to wait invoke its join method.

您可以加入该主题。您将获得该线程的实例,并在需要时等待调用其join方法。

 Thread th = new Thread(new Runnable() {  ... } );
 th.start();
 //do work 
 //when need to wait for it to finish
 th.join();
 //th has now finished

Others will suggest a CountdownLatch, CyclicBarrier or even a Future but I find this to be easiest to implement on a very low level.

其他人会建议使用CountdownLatch,CyclicBarrier甚至是Future,但我发现这是最容易在非常低的水平上实现的。

#2


3  

You have to assign your thread to a variable and later call join() on this variable.

您必须将线程分配给变量,然后在此变量上调用join()。

#3


3  

final StringBuffer outtext = new StringBuffer("");  
Thread outputDrainThread = new Thread(new Runnable() {
    public void run() {
        // ... 
    }
}).start();

// ...

//  ***HERE IS WHERE I NEED TO WAIT FOR THE THREAD TO FINISH ***
outputDrainThread.join();    

// ...
return outtext.toString();