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

Ошибка производительности Java с помощью Thread.sleep()

Внутренние подсказки Java IDE: "Вызов Thread.sleep в цикле может вызвать проблемы с производительностью". Я не могу найти разъяснения в другом месте в документации. это утверждение.

Почему? Как? Какой еще метод может быть для задержки выполнения потока?

4b9b3361

Ответ 1

Дело не в том, что Thread.sleep в самом цикле является проблемой производительности, но обычно это намек на то, что вы что-то делаете неправильно.

while(! goodToGoOnNow()) {
   Thread.sleep(1000);
}

Используйте Thread.sleep только в том случае, если вы хотите приостановить поток в течение определенного времени. Не используйте его, если вы хотите подождать определенного условия.

В этой ситуации вы должны использовать вместо wait/notify или некоторые из конструкций в пакетах concurrency utils.

Опрос с Thread.sleep должен использоваться только при ожидании условий, внешних по отношению к текущему JVM (например, до тех пор, пока другой процесс не напишет файл).

Ответ 2

Это зависит от того, зависит ли ожидание от выполнения другого потока, и в этом случае вы должны использовать охраняемые блоки или класс высокого уровня concurrency, введенный в Java 1.6. Недавно мне пришлось исправить какой-то код CircularByteBuffer, который использовал спины Thread вместо защищенных блоков. В предыдущем методе не удалось обеспечить надлежащий concurrency. Если вы просто хотите, чтобы поток спал, как игра, в цикле основной игры, чтобы приостановить выполнение в течение определенного времени, чтобы потоки имели хороший период для выполнения, Thread.sleep(..) отлично.

Ответ 3

Это зависит от того, почему вы заставляете его спать и как часто вы его запускаете.

Я могу представить несколько альтернатив, которые могут применяться в разных ситуациях:

  • Позвольте потоку умереть и начать новый позже (создание потоков также может быть дорогостоящим)
  • Используйте Thread.join(), чтобы ждать, пока другой поток не умрет.
  • Используйте Thread.yield(), чтобы разрешить запуск другого потока
  • Пусть поток запускается, но устанавливает его в более низкий приоритет
  • Использовать wait() и notify()

Ответ 4

http://www.jsresources.org/faq_performance.html

1,6. Какую точность я могу ожидать от Thread.sleep()?

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

Для Sun JDK сообщение Thread.sleep(1), как сообщается, является довольно точным в Windows. Для Linux это зависит от прерывания таймера ядра. Если ядро ​​скомпилировано с HZ = 1000 (по умолчанию по альфа), точность считается хорошей. Для HZ = 100 (по умолчанию на x86) он обычно спит в течение 20 мс.

Использование Thread.sleep(millis, nanos) не улучшает результаты. В Sun JDK наносекундное значение округляется до ближайшей миллисекунды. (Маттиас)

Ответ 5

почему? то есть из-за переключения контекста (часть планирования процессора ОС)

Как? вызов Thread.sleep(t) заставляет текущий поток перемещаться из текущей очереди в очередь ожидания. По истечении времени 't' текущий поток будет перемещен из очереди ожидания в готовую очередь, а затем потребуется некоторое время, которое будет выбрано CPU и будет запущено.

Решение: вызов Thread.sleep(t * 10); вместо вызова Thread.Sleep(t) внутри цикла из 10 итераций...

Ответ 6

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

Thread.sleep является проблемой при многопоточном сценарии. Он имеет тенденцию просыпаться. Это связано с тем, что внутренне он перестраивает свой приоритет и дает другие длительные процессы (поток).

Новый подход использует интерфейс ScheduledExecutorService или ScheduledThreadPoolExecutor, представленный в java 5.

Ссылка: http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ScheduledExecutorService.html

Ответ 7

Это может быть не проблема, это зависит.

В моем случае я использую Thread.sleep(), чтобы подождать пару секунд до повторной попытки повторного подключения к внешнему процессу. У меня есть цикл while для этой логики повторного подключения, пока он не достигнет максимального количества attemps. Так что в моем случае Thread.sleep() предназначен исключительно для назначения времени и не координируется среди многопотоков, он отлично работает.

Вы можете настроить IDE в том, как это предупреждение должно быть обработано.

Ответ 8

Я предлагаю изучить класс CountDownLatch. В Интернете есть довольно много простых примеров. Назад, когда я только начинал многопоточное программирование, они были всего лишь билетом для замены цикла "sleep while".