Использование Object.wait (миллисек) для имитации сна - PullRequest
5 голосов
/ 02 апреля 2009

Вот фрагмент кода, который я видел в некотором коде, который я поддерживаю.

Object lock = new Object();

synchronized( lock ) 
{
   try
   {
       lock.wait( 50000 );
       Thread.sleep( 3000 );
   } 
   catch(Exception ex)
   {
   }
}

Разработчик хочет приостановить текущий поток на некоторое время и использует Object # wait в качестве механизма. Очевидно, что по этой причине использовать протокол ожидания / уведомления является плохой формой; Однако есть ли существенная разница между вызовом wait (millisec) и Thread.sleep?

Ответы [ 3 ]

4 голосов
/ 02 апреля 2009

Обратите внимание, что есть одно ключевое отличие в использовании Object.wait () и Thread.sleep () внутри блока синхронизации: Thread.sleep () не освобождает заблокированный монитор, поэтому никто еще может стать владельцем монитора.

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

Во-вторых, мифическое ложное пробуждение, как оно описано в Java 6 API javadoc:

Нить тоже может проснуться без быть уведомленным, прерванным или установленным временем так называемое ложное пробуждение.

Маловероятно, что каждый кусок кода, использующий Object.wait (), должен учитывать это.

4 голосов
/ 02 апреля 2009

Кроме необходимости получать монитор перед ожиданием (), больше нет существенной разницы, пока никто не будет .notify () ing.

В древнем Java-коде вы видели бы людей, использующих wait () вместо Thread.sleep (), потому что Thread.sleep () заморозил бы все приложение в системах без упреждающей многозадачности (я смотрю на вас OS9). Технически wait () также позволяет использовать ожидания с нано-разрешением, но на практике они редко бывают такими точными.

3 голосов
/ 02 апреля 2009

Вы говорите, что это "очевидно" плохая форма - использовать ожидание / уведомление для этого, но я не вижу в этом ничего плохого. По общему признанию, после этого sleep вызов очень странен (и глотать исключения - плохо), но я определенно использовал Object.wait как «прерывистый сон» до сих пор.

Представьте, что у вас есть поток, опрашивающий ресурс каждую минуту, но вы хотите, чтобы вас разбудили, если что-то произошло (например, изменилось местоположение ресурса, или изменилась частота таймера, или программа хочет завершить работу изящно ). Использование wait/notify очень хорошо для этого работает - это, безусловно, чище, чем вызывать interrupt в потоке из другого места, так как не имеет значения, происходит ли уведомление во время обработки вместо ожидания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...