13

Разница между "wait()" и "sleep()" в Java

11

Вопрос: В чем разница между методами wait() и sleep() в потоках?

Я хочу разобраться в различиях между wait() и sleep() в контексте работы с потоками в Java.

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

Также меня интересует, почему у нас есть оба метода — wait() и sleep()?

Как различается их реализация на низком уровне?

Буду признателен за пояснения!

5 ответ(ов)

3

Одно ключевое различие, о котором ещё не было упомянуто:

  • sleep() не освобождает захваченный поток "замок":

    synchronized(LOCK) {
        Thread.sleep(1000); // LOCK остается захваченным
    }
    
  • wait() освобождает замок, который он удерживает на объекте:

    synchronized(LOCK) {
        LOCK.wait(); // LOCK не удерживается
    }
    

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

0

Существует много ответов на этот вопрос, но я не нашел упоминаемого семантического различия в них.

Дело не в самом потоке; оба метода необходимы, так как поддерживают очень разные сценарии использования.

sleep() переводит поток в спящий режим, сохраняя его контекст, и останавливает выполнение на предопределенное время. Чтобы разбудить поток до истечения этого времени, вам нужно знать ссылку на поток. Это не распространенная ситуация в многопоточной среде. Он чаще всего используется для синхронизации времени (например, пробуждение через ровно 3,5 секунды) и/или жесткого соблюдения справедливости (просто немного поспать и дать возможность поработать другим потокам).

wait(), напротив, является механизмом синхронизации потоков (или сообщений), который позволяет уведомить поток, на который у вас нет сохраненной ссылки (и о котором вы не заботитесь). Это можно рассматривать как паттерн "издатель-подписчик" (wait == подписка, а notify() == публикация). По сути, с помощью notify() вы отправляете сообщение (которое может быть вообще не получено, и, как правило, вам на это все равно).

В общем, вы обычно используете sleep() для синхронизации времени и wait() для синхронизации в многопоточной среде.

Они могут быть реализованы одинаково в базовом операционном системе или вообще не реализованы (как это было в предыдущих версиях Java, где не было настоящего многопоточности; возможно, некоторые небольшие виртуальные машины также этого не делают). Не забывайте, что Java работает на виртуальной машине, поэтому ваш код будет преобразован в нечто иное в зависимости от используемой виртуальной машины/операционной системы/аппаратного обеспечения.

0

Разница между wait() и sleep()

  • Основная разница заключается в том, что wait() является нестатическим методом класса Object, в то время как sleep() — статическим методом класса Thread.
  • Главное отличие в том, что wait() освобождает замок, в то время как sleep() не освобождает никаких замков во время ожидания.
  • wait() используется для межпоточной коммуникации, тогда как sleep() обычно применяется для введения паузы в выполнении.
  • wait() должен вызываться внутри блока синхронизации, иначе возникнет IllegalMonitorStateException, тогда как sleep() можно вызывать в любом месте.
  • Чтобы снова запустить поток из состояния wait(), необходимо вызвать notify() или notifyAll(), как бы бесконечно. В случае с sleep(), поток обязательно возобновляет выполнение после заданного времени.

Сходства

  • Оба метода переводят текущий поток в состояние Not Runnable.
  • Оба являются нативными методами.
0

Это очень простой вопрос, так как оба этих метода имеют совершенно разное назначение.

Основное различие заключается в том, что wait() освобождает блокировку или монитор, тогда как sleep() не освобождает никакую блокировку или монитор во время ожидания. wait() используется для межпоточной коммуникации, в то время как sleep() используется для введения паузы в выполнении программы.

Это было простое и ясное объяснение. Если вам нужно больше деталей, читайте дальше.

В случае метода wait() поток переходит в состояние ожидания и не вернется автоматически, пока мы не вызовем метод notify() (или notifyAll(), если у вас более одного потока в состоянии ожидания и вы хотите разбудить их всех). Для доступа к методам wait(), notify() или notifyAll() требуется синхронизированный блок, объектная блокировка или класс-лок. Также стоит отметить, что метод wait() используется для межпоточной коммуникации, поскольку, когда поток переходит в состояние ожидания, вам нужен другой поток, чтобы его разбудить.

В случае метода sleep() это метод, который используется для приостановки исполнения на несколько секунд или на тот промежуток времени, который вы хотите. Вам не нужно вызывать notify() или notifyAll(), чтобы вернуть этот поток к работе, и нет необходимости, чтобы другой поток поднимал этот поток. Например, если вы хотите, чтобы после хода пользователя в игре прошло время, прежде чем компьютер сделает свой ход, вы можете использовать метод sleep().

Еще одно важное различие, которое часто спрашивают на собеседованиях: sleep() принадлежит классу Thread, а wait() принадлежит классу Object.

Это все различия между sleep() и wait().

Также есть одно сходство между этими двумя методами: оба метода являются проверяемыми, поэтому для их использования вам необходимо обрабатывать исключения с помощью try-catch или throws.

Надеюсь, это поможет вам.

0

wait() и sleep() — это два разных метода:

  • В sleep() поток приостанавливает свою работу на указанное время.
  • В wait() поток приостанавливает свою работу до тех пор, пока объект, на который он ждет, не будет уведомлён, обычно другими потоками.
Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь