Метод Run в классе Thread не вызывается - PullRequest
0 голосов
/ 28 марта 2011

Я довольно новый парень в мире многопоточности, уже неделю пытаюсь решить эту проблему.

Метод run в классе Thread почему-то не вызывается, я незнать почему (но хотелось бы знать)

        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 - это исполняемый файл python, который принимает ввод через свой стандартный ввод, обрабатывает его и выводит несколько строк текста.Мне нужно собрать этот вывод и выполнить некоторую дальнейшую обработку.

Существует отдельный поток для обработки вывода в inputStream и errorStream.Этот класс потока показан ниже.

/* 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();  
            }
    }
}

По какой-то причине метод run в классе StreamGobbler не вызывается.Однако конструктор этого класса выполняется.

Любая помощь будет принята с благодарностью.

Ответы [ 3 ]

9 голосов
/ 28 марта 2011

Вам нужно запустить потоковых гоблеров до того, как вы позвоните process.waitFor().

Потоковые гоблеры считывают и отбрасывают потоки вывода / ошибок внешних процессов, чтобы внешний процесс не блокировался при попытке записи. Но, как вы понимаете, процесс должен завершить запись (и завершиться), прежде чем вы попытаетесь сожрать вывод.

Результат - тупик ... если внешний процесс слишком много пишет в свои выходные потоки.


На самом деле, я думаю, что основная проблема 1012 * заключается в том, что ваш Java-код ничего не записывает в inputStream. Итак, внешний процесс просто сидит в ожидании ввода, который никогда не поступит ... и process.waitFor() ожидает внешнего процесса. Тупик.

Правильный порядок вещей должен быть:

  1. построить процесс и запустить его.
  2. собрать гоблеров и запустить их.
  3. открыть входной поток.
  4. запись материала во входной поток.
  5. закрыть входной поток.
  6. позвоните process.waitFor() и проверьте код возврата процессов.
  7. посмотрите на вывод, захваченный сожителями
1 голос
/ 28 марта 2011

1) Попробуйте удалить waitFor (), если это не требуется. Это только заставляет исполняющий поток ждать, пока не завершится выполнение процесса.

1 голос
/ 28 марта 2011

Вам нужно съесть STDOUT и / или STDERR до Process.waitFor(), вот отличная статья: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=2

...