Почему Thread.sleep плохо работает
Извиняюсь за этот повторный вопрос, но пока не нашел удовлетворительных ответов. У большинства вопросов был свой собственный конкретный случай использования:
Java - альтернатива thread.sleep
Есть ли лучший или альтернативный способ пропустить/избежать использования Thread.sleep(1000) в Java?
Мой вопрос касается очень общего варианта использования. Дождитесь завершения условия. Сделайте некоторую операцию. Проверьте состояние. Если условие не соответствует действительности, подождите некоторое время и снова выполните ту же операцию.
Например, Рассмотрим метод, который создает таблицу DynamoDB, вызывая его таблицу createAPI. В таблице DynamoDB требуется некоторое время, чтобы стать активным, чтобы метод вызывал свой API-интерфейс DescribeTable для регулярного опроса статуса через некоторое время (допустим, 5 минут - отклонение из-за планирования потоков приемлемо). Возвращает true, если таблица становится активной в течение 5 минут, и выдает исключение.
Вот псевдокод:
public void createDynamoDBTable(String name) {
//call create table API to initiate table creation
//wait for table to become active
long endTime = System.currentTimeMillis() + MAX_WAIT_TIME_FOR_TABLE_CREATE;
while(System.currentTimeMillis() < endTime) {
boolean status = //call DescribeTable API to get status;
if(status) {
//status is now true, return
return
} else {
try {
Thread.sleep(10*1000);
} catch(InterruptedException e) {
}
}
}
throw new RuntimeException("Table still not created");
}
Я понимаю, что при использовании Thread.sleep
блокирует текущий поток, тем самым потребляя ресурсы. но в приложении с довольно большим размером, это одна проблема, большая проблема?
Я где-то читал, что использую ScheduledThreadPoolExecutor
и делаю там этот статус. Но опять же, нам нужно будет инициализировать этот пул, по крайней мере, с одним потоком, где будет выполняться метод runnable для выполнения опроса.
Любые предложения о том, почему использование Thread.sleep
говорят, являются такой плохой идеей и каковы альтернативные варианты для достижения того же, что и выше.
http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx
Ответы
Ответ 1
Хорошо использовать Thread.sleep
в этой ситуации. Причина, по которой люди отговаривают Thread.sleep
, состоит в том, что она часто используется при плохой попытке исправить состояние гонки, используется там, где синхронизация на основе уведомлений является гораздо лучшим выбором и т.д.
В этом случае AFAIK у вас нет опции, кроме опроса, потому что API не предоставляет вам уведомления. Я также вижу, что это редкая операция, потому что, по-видимому, вы не собираетесь создавать тысячи таблиц.
Поэтому я считаю, что здесь можно использовать Thread.sleep
. Как вы сказали, нереста отдельного потока, когда вы собираетесь блокировать текущий поток в любом случае, кажется, осложняет ситуацию без заслуг.
Ответ 2
Да, нужно стараться избегать использования Thread.sleep(x), но его нельзя полностью забыть:
Почему этого следует избегать
- Он не освобождает блокировку
- Это не гарантирует, что выполнение начнется после спящего времени (так что он может продолжать ждать вечно - , очевидно, редкий случай)
- Если мы ошибочно поместим поток обработки переднего плана в сон, мы не сможем закрыть это приложение до x миллисекунд.
- Теперь мы загружены новым пакетом concurrency для конкретных проблем (например, шаблоны проектирования (, конечно, не точно)), зачем использовать Thread.sleep(x).
Где использовать Thread.sleep(x):
- Для обеспечения задержек в фоновом режиме потоков
- И несколько других.