Распараллелить блокирующий вызов в Java - PullRequest
0 голосов
/ 11 июля 2011

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

Process p = Runtime.getRuntime().exec(executablePath);
ProcessWatcher pw = new ProcessWatcher(p);
BufferedReader output = new BufferedReader(new InputStreamReader(p.getInputStream()));
while(!pw.isFinished()) {
    String line = output.readLine();
    if(line != null) {
        System.out.println(line);
    }
    // I want to do something in parallel here
}

Моя проблема была бы решена, если бы я мог дать вызову readLine () какое-то время ожидания, или если бы я мог запустить его в своем собственном потоке. Последнее было бы предпочтительным, но первое приемлемо. Мое основное намерение - сделать код простым.

Есть ли хороший, простой способ распараллелить блокирующий вызов, или мне нужно будет создать новый класс, который реализует Runnable только для этого?

Ответы [ 3 ]

5 голосов
/ 11 июля 2011

Вы можете свернуть свой код с помощью.

new Thread(new Runnable() { public void run() {
///put your code here
}}).start();

Вы не можете сделать неблокирующую readLine или одну с тайм-аутом. В любом случае, написание кода для обработки неблокирующих соединений обычно в 10 раз сложнее. ;)

1 голос
/ 11 июля 2011

Вызов readLine() действительно блокирует, однако вызов ready() на BufferedReader - нет, так что вы можете проверить, готов ли ваш ридер (неблокирующий вызов), а затем выполнить чтение - что-товот так:

Process p = Runtime.getRuntime().exec(executablePath);
ProcessWatcher pw = new ProcessWatcher(p);
BufferedReader output = new BufferedReader(new InputStreamReader(p.getInputStream()));
while(!pw.isFinished()) {
  if( output.ready() ) {
    String line = output.readLine();
    if(line != null) {
        System.out.println(line);
    }
  }
    // I want to do something in parallel here
}

Это позволит вам выполнить что-то еще в цикле while во время выполнения процесса.

0 голосов
/ 11 июля 2011

IMO, вам было бы лучше поместить «порождающий процесс» материал в отдельный поток выполнения, поскольку порождение процесса может занять неопределенное количество времени, не говоря уже о множестве вещей, которые могут пойти не так. Объединить все эти вещи в отдельную логическую единицу было бы намного чище.

...