Ошибка производительности Java с помощью Thread.sleep()
Внутренние подсказки Java IDE: "Вызов Thread.sleep в цикле может вызвать проблемы с производительностью". Я не могу найти разъяснения в другом месте в документации. это утверждение.
Почему? Как? Какой еще метод может быть для задержки выполнения потока?
Ответы
Ответ 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".