开发者

Run Method in the Thread class not being called

开发者 https://www.devze.com 2023-02-20 00:55 出处:网络
I am a pretty new guy to the world of threading, have been trying to solve this problem for a week now.

I am a pretty new guy to the world of threading, have been trying to solve this problem for a week now.

The run method in the Thread class is not being called for some reason, I dont know 开发者_JAVA技巧why ( but would love to know)

        ProcessBuilder processBuilder = new ProcessBuilder();

        processBuilder.command("/bin/sh", "-c", "echo \"w30000001z,none,16488,,181075\nw30000001z,none,16488,,181082\n\" | /home/beehive/bin/exec/tableSize");
        Process process = processBuilder.start();
        process.waitFor(); 

        InputStream stdin = process.getInputStream();
        OutputStream stdout = process.getOutputStream();
        InputStream stderr = process.getErrorStream();

        BufferedReader reader = new BufferedReader(new InputStreamReader(stdin));
        BufferedReader error = new BufferedReader(new InputStreamReader(stderr));
        StreamGobbler errorStream = new StreamGobbler(process.getErrorStream(), "ERROR");
        StreamGobbler outputStream = new StreamGobbler(process.getInputStream(), "OUTPUT");

        errorStream.start();
        outputStream.start();
        errorStream.join();
        outputStream.join();

tableSize is a python executable which takes input through its stdin, processes it and outputs a few lines of text. I need to collect this output and do some further processing on it.

There is a separate thread to process the output on the inputStream and errorStream. This thread class is as shown below.

/* StreamGobbler.java */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;

class StreamGobbler extends Thread
{
    InputStream is;
    String type;
    OutputStream os;

    StreamGobbler(InputStream is, String type)
    {
        this(is, type, null);

    }
    StreamGobbler(InputStream is, String type, OutputStream redirect)
    {
        this.is = is;
        this.type = type;
        this.os = redirect;
    }

    public void run()
    {
        try
        {
            PrintWriter pw = null;
            if (os != null)
                pw = new PrintWriter(os);

            System.out.println("Ajay" + type);
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line=null;
            while ( (line = br.readLine()) != null)
            {
                if (pw != null)
                    pw.println(line);
                System.out.println(type + ">" + line);    
            }
            if (pw != null)
                pw.flush();
        } catch (IOException ioe)
            {
            ioe.printStackTrace();  
            }
    }
}

For some reason, the run method in the StreamGobbler class is not being called. However the constructor of this class is being executed.

Any help would be much appreciated.


You need to start the stream gobblers before you call process.waitFor().

The stream gobblers read and discard the external processes output / error streams so that the external process doesn't block while trying to write. But the way you have it, the process has to have finished writing (and exited) before you attempt to gobble the output.

Result - deadlock ... if the external process writes too much to its output streams.


Actually, I think that the primary problem is that your Java code does not write anything to inputStream. So, the external process just sits there waiting for input that never arrives ... and process.waitFor() waits for the external process. Deadlock.

The correct order of things should be:

  1. build the process and start it.
  2. build the gobblers and start them.
  3. open the input stream.
  4. write stuff to input stream.
  5. close input stream.
  6. call process.waitFor() and check the processes return code.
  7. look at the output captured by the gobblers


You need consume the STDOUT and/or STDERR before Process.waitFor(), here's an excellent article: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=2


1) Try removing the waitFor() if it is not required. It only makes the executing thread wait until the process execution is completed.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号