2016-05-06 2 views
6

В последнее время я сделал очень простую программу. Счетчик времени, который имеет возможность приостановки. Он работал с 3 нитями, 2 для Swing и 1 для основной нити.while (true) loop или java.util.Timer для стандартного цикла программы?

Для этой программы в основной нити должна быть часть времени дельта-времени. Я создал такую ​​базовую систему;

while(true) 
{ 
    long now = System.currentTimeMillis(); 

    if(!sessionPaused) 
    { 
     if(now-programLastMs>1000) 
     { 
      save(); 
      programLastMs = now; 
     } 
     sessionMs += now-sessionPrevMs; 
     overallMs += now-sessionPrevMs; 

     sessionPrevMs = now; 
     sessionLabel.setText(formatMillis("This Session:<br/>",sessionMs)); 
     overallLabel.setText(formatMillis("Overall:<br/>", overallMs)); 
    } 
} 

Этот код, приведенный выше, вызвал высокий уровень использования ЦП. Затем я заменил этот кусок кода на:

timer.scheduleAtFixedRate(new TimerTask() { 
      @Override 
      public void run() { 

       long now = System.currentTimeMillis(); 

       if(!sessionPaused) 
       { 
        if(now-programLastMs>1000) 
        { 
         save(); 
         programLastMs = now; 
        } 

        sessionMs += now-sessionPrevMs; 
        overallMs += now-sessionPrevMs; 

        sessionPrevMs = now; 

        sessionLabel.setText(formatMillis("This Session:<br/>",sessionMs)); 
        overallLabel.setText(formatMillis("Overall:<br/>", overallMs)); 
       } 
      } 
     }, 0, 1); 

И проблема исчезла. Мне просто интересно, почему. Также каков оптимальный способ создания цикла программы?

+3

Ваш цикл while (true) 'не делает паузы, поэтому цикл постоянно работает и постоянно питается CPU. Планирование делает ваш метод 'run' выполненным, только когда он запланирован. – Berger

+0

Итак, если бы я сделал планировщик, назовите его один раз за 50 наносекундов, будет ли он таким же?И все же каков оптимальный способ создания цикла программы? @Berger – iGoodie

+0

Это зависит от продолжительности вашего метода 'run', но 50 наносекунд действительно низкое, вам нужна такая высокая частота? Однако, как вы это видели, лучше позволить вашему приложению дышать, поэтому либо используйте планировщик, либо добавьте 'Thread.sleep' в свой цикл while. – Berger

ответ

5

Ваш первый блок кода в основном работает со скоростью процессора. Чтобы понять это, вам нужно знать, что такое IPS и FLOPS. Современный процессор делает несколько GFLOPS, что означает, что ваш 1-й блок будет выполняться десятками или даже сотнями тысяч раз в секунду в зависимости от вашего оборудования. Если вы запустите его в основном потоке, он заблокирует ваш пользовательский интерфейс (т. Е. Ваш графический интерфейс застрянет). В отдельном потоке он будет работать непрерывно, занимая ресурсы, фактически не делая много.

Второй блок, с другой стороны, имеет конкретные инструкции для выполнения каждой миллисекунды. Это означает, что ваш блок кода выполняется 1000 раз, а оставшаяся часть процессора освобождается для другой работы.

Чтобы ответить на вопрос в вашем комментарии: почти никогда нельзя использовать бесконечный цикл. Петли лучше всего использовать для ограниченного повторения набора инструкций. В вашем примере кажется, что вы хотите вызвать сохранение каждые 1000 мс, а также подсчитать время сеанса. Я бы

  1. Отделить сохранение до повторяющегося таймера, который вызывается каждые 1000 мс.
  2. Создайте onSessionPause и onSessionResume, которые только при изменении состояния паузы. Это может быть связано с кнопкой паузы или другим определением, которое вы определяете. Функции onSessionPause и onSessionResume должны иметь возможность записывать время, в которое они вызываются, и обновлять sessionMs на основе разницы во времени.

Если вы не ожидали изменений в каждой миллисекунде, вы делаете CPU ненужной работой.

+0

Это был прекрасный ответ, который я искал. Спасибо за подробную информацию (Y) – iGoodie

0

Также каков оптимальный способ создания цикла программы?

В вашем конкретном случае оптимальным способом будет цикл, выполняющийся один раз в секунду, поскольку это достигнет вашей цели при минимальном использовании ЦП. Поскольку это невозможно гарантировать, вам нужно найти порог достаточно низкий, поэтому ваш цикл выполняется не реже одного раза в секунду, а не слишком низко, чтобы быть эффективным. Я бы посоветовал вам протестировать некоторые результаты.

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

Смежные вопросы