2016-11-29 1 views
0

У меня есть программа Java, которая (в том числе и прочее) читается из внешнего приложения Python с использованием Input Stream.Чтение внешнего процесса Ошибка потока сильно влияет на производительность

Вот код, я использую, чтобы читать:

InputStreamReader isr = new InputStreamReader(p.getInputStream()), 
      isrError = new InputStreamReader(p.getErrorStream()); 

BufferedReader br = new BufferedReader(isr), brError = new BufferedReader(isrError); 
new Thread() { 
    @Override 
    public void run() { 
     try { 
      while (brError.readLine() != null); 

     } catch (Exception e) { 
     } 
    } 
}.start(); 
while ((line = br.readLine()) != null) { //line is a previously declared String 
    //do whatever with line 
} 

Я создаю нить прочитать ошибку потока тоже, потому что приложение Python бросает ошибки, когда что-то идет не так (я не могу изменить его, это программное обеспечение сторонних производителей), и по какой-то причине в конце концов InputStream блокируется, если я не читаю ErrorStream.

Есть ли способ сделать while (brError.readLine() != null); оказывают меньшее влияние на производительность?

Прямо сейчас я смотрю на производительность с помощью VisualVM, и хотя программное обеспечение Java обычно остается между 0-5% использования ЦП, что довольно хорошо, но около 60-65% этого использования используется этим циклом в этот поток, который работает только для предотвращения блокировки основного цикла. И мне нужно как можно больше улучшить производительность (это происходит в промышленных линиях, поэтому правильное использование ресурсов действительно важно).

Спасибо всем.

ответ

1

Для удобства использования (если вам не нужно содержимое во время работы), используйте redirectError(File) в ProcessBuilder.

ProcessBuilder pb = new ProcessBuilder("foo", "-bar"); 
pb.redirectError(new File("/tmp/errors.log")); 
pb.start(); 

Если вы получаете от центрального процессора спиннинг while (brError.readLine() != null);, вы должны смотреть на то, что возвращает поток ошибок. Поскольку readLine() является блокирующим вызовом, это означает, что поток ошибок перекачивает много строк.

+0

Но мне все равно, что Ошибки (я, наверное, должен был упомянуть об этом раньше). Я просто «читаю» их, чтобы они не блокировали фактический InputStream, но меня вообще не волнуют ошибки. – Tuzane

+0

@Mayuso Затем перенаправить его на '/ dev/null'? – Kayaman

+0

Это действительно имеет смысл, будет ли это лучше, чем мое текущее решение? Думаю, я должен попробовать. – Tuzane

0

Вы произвольно конвертируете поток выброса в символы, что может быть немного дорогостоящим, особенно если вы используете UTF-8 (в любом случае, в зависимости от платформы, кодирование обычно неверно).

Оставьте Reader, используйте BufferedInputStream для потока выброса.

Однако для внешних процессов перенаправление, безусловно, превосходит, поскольку в Java нет обработки вообще.