2013-07-24 5 views
16

Извинения за этот повторяющийся вопрос, но пока я еще не нашел удовлетворительных ответов. Большая часть вопроса имел свой собственный специфический случай использования:
Java - alternative to thread.sleep
Is there any better or alternative way to skip/avoid using Thread.sleep(1000) in Java?Почему Thread.sleep вреден для использования

Мой вопрос для очень общего использования. Дождитесь завершения условия. Сделайте некоторую операцию. Проверьте состояние. Если условие не соответствует действительности, подождите некоторое время и снова выполните ту же операцию.

См., Например, Рассмотрим метод, который создает таблицу 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

+2

http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx – stinepike

+4

Ваша ссылка о .Net. Это не относится к Java. –

+0

Опрос - это плохо, без сомнения. Но если у вас нет альтернатив, это самое меньшее, о чем вы должны заботиться. –

ответ

24

Это прекрасно, чтобы использовать Thread.sleep в этой ситуации. Причина, по которой люди отказываются от Thread.sleep, заключается в том, что она часто используется при плохой попытке исправить состояние гонки, используется там, где синхронизация на основе уведомлений является гораздо лучшим выбором и т. Д.

В этом случае у AFAIK у вас нет возможности, кроме опроса потому что API не предоставляет вам уведомления. Я также вижу, что это редкая операция, потому что, по-видимому, вы не собираетесь создавать тысячи таблиц.

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

+9

Одно большое предостережение: убедитесь, что спальная нить не держится на скудных ресурсах, таких как соединение мьютекса или базы данных. – yshavit

+0

Будет ли этот шаблон также приемлемым в следующем случае? - Опрос SQS для одного сообщения за раз и ведение списка сообщений. Когда размер списка достигнет номера X, обработайте их навалом. Если в SQS больше нет сообщений, сон в течение некоторого времени. Опять опрос после этого. – RandomQuestion

+0

@Jitendra: Обычно с помощью MQ вы хотите избежать опроса, но AFAIK нет другого способа опроса в SQS (который, кстати, они платят, даже когда нет сообщения), поэтому 'Thread.sleep' является вариант. Возможно, я склонен использовать запланированного исполнителя, потому что это упрощает добавление потребителей, прекращает планирование опроса и заставляет вас отделять бизнес-логику и инфраструктуру. –

2

Да, следует стараться избегать использования Thread.sleep (х), но это не должно быть полностью забыто:

Почему следует избегать

  • Это не освобождает замок
  • это не гарантируем, что выполнение начнется после того, как время сна (так он может держать ждать вечно - явно редкий случай)
  • Если мы по ошибке поставить передний план обработки нити на сон, то мы чюо uldn't сможет закрыть это приложение до x миллисекунд.
  • Теперь мы загружены новым пакетом параллелизма для конкретных проблем (например, шаблоны проектирования (), а не точно), зачем использовать Thread.sleep (x).

Где использовать Thread.sleep (х):

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

Не используйте форматирование цитаты для текста, который не цитируется. – EJP