Почему 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):

  • Для обеспечения задержек в фоновом режиме потоков
  • И несколько других.