Почему переключение с бесконечного цикла на TimerTask вызвало такое снижение загрузки процессора? - PullRequest
10 голосов
/ 08 января 2012

Я написал демон, который был структурирован следующим образом:

while( true ) {
  // do some stuff
  Thread.sleep( 1000 );
}

Я заметил, что он использует очень большое количество процессора - до 100%.У меня в течение нескольких месяцев был аналогичный демон на моих производственных серверах с той же самой проблемой с процессором.

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

Load average

CPU usage

Пара моментов:

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

Итак: почему Thread.sleep неэффективен по сравнению с TimerTask?

Ответы [ 2 ]

11 голосов
/ 08 января 2012

Три возможности, которые я могу придумать:

  • У вас есть огромное количество потоков, которые делают это, и они постоянно переключаются между контекстами. Использование таймера будет означать, что вместо этого есть только один поток. С другой стороны, это означает, что вы можете одновременно выполнять только одну задачу.
  • У вас есть оператор continue; где-то в вашем цикле перед сном, поэтому, даже если основная часть работы цикла выполняется не очень часто, что-то есть. Трудно сказать, не видя более конкретного кода.
  • У вас неисправная комбинация JVM / OS. По общему признанию это кажется маловероятным.

Простой цикл просто многократное выполнение Thread.sleep(1000) должен быть очень дешевым - и это тоже будет легко проверить.

0 голосов
/ 18 мая 2017

Сравните скорость вашего процессора, потока и таймерной задачи.Таймерная задача - более медленный поток (намного медленнее).

...