Является ли непрерывным время цикла? - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть фрагмент RXTX Образец последовательной связи:

public static class SerialReader implements Runnable {
    InputStream in;

    public SerialReader(InputStream in) {
        this.in = in;
    }

    public void run(){
        byte[] buffer = new byte[1024];
        int len = -1;
        try {
            while ((len = this.in.read(buffer)) > -1){
                System.out.print(new String(buffer,0,len));   
            }    
        }
        catch(IOException e) {
            e.printStackTrace();
        }            
    }
}

Мне интересно относительно while цикла. Насколько я понимаю, такой бесконечный цикл должен быть избыточным для системы, и его следует избегать. Но когда я посмотрел диспетчер рекламных задач, я не смог найти значительную нагрузку.

Затем я изменил цикл while, как показано ниже, и получил перегрузку системы.

        while (true) {
            System.out.print(new String(buffer,0,0));
        }

Почему первый подход не создает большой нагрузки? Как я могу сделать второй цикл, чтобы сделать не очень голодным для CPU? Целесообразно ли вообще использовать такие алгоритмы?

1 Ответ

0 голосов
/ 06 ноября 2018

Операция in.read(buffer) занимает некоторое время, потому что ваша программа ожидает ввода / вывода, чтобы вернуть следующий символ.

Это так называемый blocking operation. Из Javadoc: This method blocks until input data is available, the end of the stream is detected, or an exception is thrown. Итак, в этом случае каждая итерация цикла происходит не так часто, поэтому она не генерирует высокую нагрузку.

Как отметил Майк Робинсон, этот вид отключения можно также назвать busy wait.

В вашем втором примере while(true) ничего не ждет. Поэтому между последовательными итерациями нет задержки, и это создает очень высокую нагрузку.

Конечно, если передатчик RXTX будет очень быстрым, он может истощить ресурсы ЦП / памяти. В этом случае, возможно, было бы неплохо добавить ограничение памяти / ЦП для ваших приложений. Вы также можете читать символы в чанках (в InputStream есть перегруженный метод read, который может читать некоторое количество символов) и добавлять, возможно, некоторую задержку между чтениями.

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

...