Подтвердить что ты не робот

Thread.sleep() VS Executor.scheduleWithFixedDelay()

Цель: Выполнять определенный код каждый раз.

Вопрос: Что касается производительности, существует ли существенная разница между:

while(true) {
    execute();
    Thread.sleep(10 * 1000);
}

и

executor.scheduleWithFixedDelay(runnableWithoutSleep, 0, 10, TimeUnit.SECONDS);

?

Конечно, последний вариант более кошерный. Тем не менее, я хотел бы знать, должен ли я приступить к приключению под названием "Провести несколько дней рефакторинг устаревшего кода, чтобы попрощаться с Thread.sleep()".

Обновление: Этот код работает в среде super/mega/hyper high-load.

4b9b3361

Ответ 1

Вы имеете дело со временем сна, называемым десятками секунд. Возможная экономия, изменяя ваш вариант сна здесь, вероятно, наносекунды или микросекунды.

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

EDIT re: 8000 потоков

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

Я потратил бы время, чтобы выбросить все это в фиксированный пул запланированных исполнителей. У вас будет столько одновременных одновременных действий, поскольку у вас есть доступ к самому ограниченному ресурсу (например, # ядрам или путям # IO), а также нескольким, чтобы забрать любую отставку. Это даст вам хорошую пропускную способность за счет латентности.

С помощью метода Thread.sleep() будет очень сложно управлять тем, что происходит, и вы, вероятно, проиграете как пропускную способность, так и задержку.

Если вам нужен более подробный совет, вам, вероятно, придется описать, что вы пытаетесь сделать более подробно.

Ответ 2

Поскольку вы не упомянули версию Java, так что все может измениться.

Как я помню из исходного кода Java, основное отличие, которое приходит, - это то, как вещи написаны внутри.

Для Sun Java 1.6, если вы используете второй подход, собственный код также вызывает вызовы wait и notify в систему. Таким образом, в некотором смысле более эффективный поток и удобный для ЦП.

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

Итак, если вы хотите большей предсказуемости, вы можете пойти с опцией 1.

Кроме того, на стороне примечания, в унаследованных системах, когда вы сталкиваетесь с такими вещами - 80% шансов на то, что теперь есть лучшие способы сделать это, - но волшебные числа существуют по какой-либо причине (остальные 20%), изменить его на свой страх и риск:)

Ответ 3

Существуют разные сценарии,

  • Таймер создает очередь задач, которые постоянно обновляются. Когда таймер будет выполнен, он может не быть собранным немедленно. Таким образом, создание большего количества таймеров добавляет больше объектов в кучу. Thread.sleep() только приостанавливает поток, поэтому накладные расходы памяти будут крайне низкими.
  • Timer/TimerTask также учитывает время выполнения вашей задачи, поэтому он будет немного более точным. И он лучше справляется с проблемами многопоточности (например, избегая взаимоблокировок и т.д.).
  • Если вы используете исключение и убиваете, это проблема. Но TimerTask позаботится об этом. Он будет работать независимо от отказа в предыдущем запуске
  • Преимущество TimerTask заключается в том, что он значительно улучшает ваше намерение (то есть читаемость кода), и у него уже есть функция cancel().

Ссылка взята из здесь