пример - thread.sleep java




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

В чем разница между wait() и sleep() в Threads?

Насколько я понимаю, что поток wait() -Thread по-прежнему работает в режиме работы и использует циклы процессора, но sleep() -ing не требует каких-либо циклов процессора?

Почему у нас есть wait() и sleep() : как их реализация меняется на более низком уровне?


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

  • Основное отличие - wait() от Object и sleep() - статический метод Thread .

  • Основное различие заключается в том, что wait() освобождает блокировку, в то время как sleep() не освобождает блокировку во время ожидания.

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

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

  • Чтобы снова запустить поток из wait() , вам нужно вызвать notifyAll() или notifyAll() . Во время sleep(), поток запускается после указанного интервала ms / sec.

Сходства, которые помогают понять

  • Оба делают текущий поток переходит в состояние « Не работает» .
  • Оба являются native методами.

спать

  • Это заставляет текущий исполняемый поток спать в течение определенного времени.
  • Его точность зависит от системных таймеров и планировщиков.
  • Он держит мониторы, которые он приобрел, поэтому, если он вызывается из синхронного контекста, ни один другой поток не может ввести этот блок или метод.
  • Если мы вызываем метод interrupt (), он пробудит спящий поток.

Подождите

  • Он заставляет текущий поток ждать, пока другой поток не вызовет метод notify () или метод notifyAll () для этого объекта
  • Он должен вызываться из синхронизированного контекста, т. Е. Из блока или метода. Это означает, что до вызова метода wait () текущий поток должен иметь блокировку для этого объекта.
  • Он освобождает блокировку объекта, на который он вызывается и добавляется в список ожидания, поэтому другой поток может получить блокировку объекта.

Вы правы - Sleep () заставляет этот поток «поспать», и процессор выключится и обработает другие потоки (иначе известный как переключение контекста), поскольку я считаю, что Wait поддерживает обработку процессора текущей нитью.

У нас есть и то, и другое, потому что, хотя может показаться разумным позволить другим людям использовать процессор, пока вы его не используете, на самом деле есть накладные расходы на переключение контекста - в зависимости от продолжительности сна, это может быть более дорогостоящим в циклах процессора для переключения потоков, чем просто для того, чтобы ваш поток ничего не делал в течение нескольких мс.

Также обратите внимание, что сон заставляет контекстный переключатель.

Кроме того, в общем случае невозможно управлять переключением контекста - во время ожидания ОС может (и для более длительного ожидания) выбирать для обработки других потоков.


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

Пример1 : использование wait () и sleep ():

synchronized(HandObject) {
    while(isHandFree() == false) {
        /* Hand is still busy on happy coding or something else, please wait */
        HandObject.wait();
    }
}

/* Get lock ^^, It is my turn, take a cup beer now */
while (beerIsAvailable() == false) {
    /* Beer is still coming, not available, Hand still hold glass to get beer,
       don't release hand to perform other task */
    Thread.sleep(5000);
}

/* Enjoy my beer now ^^ */
drinkBeers();

/* I have drink enough, now hand can continue with other task: continue coding */
setHandFreeState(true);
synchronized(HandObject) {
    HandObject.notifyAll();
}

Пусть ясность некоторые ключевые замечания:

  1. Позвоните :
    • wait (): вызывать текущий поток, содержащий объект HandObject
    • sleep (): Call on Thread выполнить задачу get beer (метод класса так влияет на текущий текущий поток)
  2. Синхронизировано :
    • wait (): когда синхронизированный доступ к нескольким потокам относится к одному объекту (HandObject) (когда требуется связь между несколькими потоками (выполнение выполнения потока, поток выполнить получение пива) на одном объекте HandObject)
    • sleep (): при ожидании условия продолжения выполнения (доступно ожидаемое пиво)
  3. Удерживать замок :
    • wait (): отпустите блокировку для другого объекта, чтобы иметь возможность выполнить (HandObject свободен, вы можете выполнять другое задание)
    • sleep (): удерживайте блокировку не менее чем в t раз (или до прерывания) (Моя работа еще не закончена, я продолжаю удерживать блокировку и жду некоторых условий для продолжения)
  4. Состояние пробуждения :
    • wait (): до вызова notify (), notifyAll () из объекта
    • sleep (): до тех пор, пока не истечет время или прерывание вызова
  5. И последний момент - использование, когда, как указывают estani

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

Пожалуйста, поправьте меня, если я ошибаюсь.


Здесь много ответов, но я не мог найти семантическое различие, упомянутое на любом.

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

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

wait() , напротив, является механизмом синхронизации потоков (или сообщений), который позволяет вам уведомлять нить, у которой у вас нет хранимой ссылки (и не заботы). Вы можете рассматривать это как шаблон публикации-подписки ( wait == subscribe and notify() == publish). В основном, используя notify (), вы отправляете сообщение (которое может даже не быть получено вообще, и обычно вам все равно).

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

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


Здесь я перечислял несколько важных различий между методами wait() и sleep() .
PS: Также нажмите на ссылки, чтобы увидеть код библиотеки (внутренняя работа, просто немного поиграйте для лучшего понимания).

wait()

  1. Метод wait() освобождает блокировку.
  2. wait() - это метод класса Object .
  3. wait() - нестатический метод - public final void wait() throws InterruptedException { //...}
  4. wait() должен быть уведомлен методами notifyAll() или notifyAll() .
  5. wait() необходимо вызвать из цикла, чтобы справиться с ложным сигналом тревоги.

  6. wait() должен вызываться из синхронного контекста (например, синхронизированного метода или блока), иначе он будет IllegalMonitorStateException

sleep()

  1. sleep() не освобождает блокировку.
  2. sleep() - это метод класса java.lang.Thread .
  3. sleep() - статический метод - public static void sleep(long millis, int nanos) throws InterruptedException { //... }
  4. после указанного количества времени sleep() завершается.
  5. sleep() лучше не звонить из цикла (т.е. см. код ниже ).
  6. sleep() может вызываться из любого места. особых требований нет.

Ссылка: разница между ожиданием и сном

Фрагмент кода для вызова метода ожидания и сна

synchronized(monitor){
    while(condition == true){ 
        monitor.wait()  //releases monitor lock
    }

    Thread.sleep(100); //puts current thread on Sleep    
}


Методы используются для разных вещей.

Thread.sleep(5000);   // Wait until the time has passed.

Object.wait();        // Wait until some other thread tells me to wake up.

Thread.sleep (n) может быть прерван, но Object.wait () должен быть уведомлен. Можно указать максимальное время ожидания: Object.wait(5000)так можно было бы использовать wait, er, sleepно тогда вам придется беспокоиться о блокировках.

Ни один из методов не использует процессор во время сна / ожидания.

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

Посмотрите сами: доступен ли исходный код собственных методов? Файл /src/share/vm/prims/jvm.cppявляется отправной точкой ...


Одна потенциальная большая разница между сном / прерыванием и ожиданием / уведомлением заключается в том, что

Генерирование исключения, когда оно не требуется, является неэффективным. Если у вас есть потоки, обменивающиеся друг с другом с высокой скоростью, тогда это будет генерировать множество исключений, если вы все время вызываете прерывание, что является полной потерей процессора.


Простыми словами ждать ждать До тех пор, пока какой-то другой поток не вызовет вас, тогда как sleep «не выполняет следующий оператор» в течение определенного периода времени.

Кроме того, сон является статическим методом в классе Thread, и он работает с потоком, тогда как wait () находится в классе Object и вызывает объект.

Другой момент, когда вы вызываете wait на каком-то объекте, поток задействует синхронизацию объекта, а затем ждет. :)


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

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

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

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

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

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

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

И есть сходство между обоими методами: оба они проверены, поэтому вам нужно попробовать catch или throw для доступа к этим методам.

Я надеюсь, что это поможет вам.


источник: http://www.jguru.com/faq/view.jsp?EID=47127

Thread.sleep() отправляет текущий поток в состояние «Не запускается» в течение некоторого времени. Поток поддерживает мониторы, которые он приобрел - т.е. если поток в настоящее время находится в синхронизированном блоке или методе, ни один другой поток не может ввести этот блок или метод. Если другой поток вызывает t.interrupt() он пробудит спящий поток.

Обратите внимание, что сон является статическим методом, что означает, что он всегда влияет на текущий поток (тот, который выполняет метод сна). Общей ошибкой является вызов t.sleep() где t - другой поток; даже тогда, это текущий поток, который будет спать, а не поток t.

t.suspend() устарел. Используя его можно остановить поток, отличный от текущего потока. Подвешенная нить хранит все свои мониторы, и поскольку это состояние не прерывается, оно является тупиковым.

object.wait() отправляет текущий поток в состояние «Не запускается» , например sleep() , но с завихрением. Ожидание вызывается на объект, а не на поток; мы называем этот объект «объектом блокировки». Перед lock.wait() текущий поток должен синхронизировать объект блокировки; wait() затем освобождает эту блокировку и добавляет поток в список ожидания, связанный с блокировкой. Позже другой поток может синхронизироваться на одном и том же объекте блокировки и вызвать lock.notify() . Это пробуждает оригинальную, ожидающую нитку. В принципе, wait() / notify() подобен sleep() / interrupt() , только активный поток не нуждается в прямом указателе на спящий поток, а только на общий объект блокировки.


методы wait и sleep очень разные:

  • Thread.sleep() имеет никакого способа «просыпаться»,
  • тогда как object.wait() имеет способ «пробуждения» в течение периода ожидания, другим потоком, вызывающим notify или notifyAll .

Подумайте об этом, имена запутаны в этом отношении; однако sleep является стандартным именем, и wait похоже на WaitForSingleObject или WaitForMultipleObjects в Win API.


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

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


sleep - это метод Thread , wait - это метод Object , поэтому wait/notify - это метод синхронизации общих данных на Java (с использованием monitor ), но sleep - это простой метод потоковой передачи, чтобы сделать паузу.


waitосвобождает замок и sleepне делает этого. Поток в состоянии ожидания имеет право на пробуждение сразу notifyили notifyAllвызвано. Но в случае, sleepесли поток держит замок, и он будет иметь право только после завершения сна.


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

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

Thread.sleep () отправляет текущий поток в состояние «Не запускается» в течение некоторого времени. В потоке хранятся мониторы, которые он приобрел, т.е. если поток в настоящее время находится в синхронизированном блоке или методе, ни один другой поток не может ввести этот блок или метод. Если другой поток вызывает t.interrupt (), он пробудит спящий поток. Обратите внимание, что сон является статическим методом, что означает, что он всегда влияет на текущий поток (тот, который выполняет метод сна). Общей ошибкой является вызов t.sleep (), где t - другой поток; даже тогда, это текущий поток, который будет спать, а не поток t.

object.wait () отправляет текущий поток в состояние «Не запускается», например sleep (), но с завихрением. Ожидание вызывается на объект, а не на поток; мы вызываем этот объект «объектом блокировки». Перед вызовом функции lock.wait () текущий поток должен синхронизировать объект блокировки; wait () затем освобождает эту блокировку и добавляет поток в список ожидания, связанный с блокировкой. Позже другой поток может синхронизироваться на одном и том же объекте блокировки и вызвать lock.notify (). Это пробуждает оригинальную, ожидающую нитку. В принципе, wait () / notify () подобен sleep () / interrupt (), только активный поток не нуждается в прямом указателе на спящий поток, а только на общий объект блокировки.

synchronized(LOCK) {   
   Thread.sleep(1000); // LOCK is held
}

synchronized(LOCK) {   
   LOCK.wait(); // LOCK is not held
}

Позвольте классифицировать все вышеперечисленные моменты:

Call on:

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

Synchronized:

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

Hold lock:

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

Wake-up condition:

  • wait (): до вызова notify (), notifyAll () из объекта
  • sleep (): до истечения по крайней мере времени или прерывания вызова ().

Usage:

  • sleep (): для синхронизации времени и;
  • wait (): для многопоточной синхронизации.

Ссылка: diff sleep и wait


Wait () и sleep () Различия?

Thread.sleep () После того, как его работа завершена, тогда только его освобождение блокируется для всех. пока он никогда не выпустит замок никому.

  Sleep() take the key, its never release the key to anyone, when its work completed then only its release then only take the key waiting stage threads.

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

Например:

вы берете кофе в свою правую руку, вы можете взять другого кого-то из той же руки, когда вы положите его, а затем возьмите другой объект такого же типа здесь. также. это сон () вы спите время, когда у вас не было никакой работы, вы делаете только сон ... тоже здесь.

Подождите(). когда вы ставите и принимаете еще одно среднее, пока вы ждете, это ждет

вы играете в кино или что-то в вашей системе, так же, как и игрок, вы не можете играть более одного раза за раз, вот и здесь, когда вы закрываете и выбираете другого, что любой фильм или песня означает, что он называется wait


Здесь wait () будет находиться в состоянии ожидания, пока он не уведомит другой поток, но где, когда sleep () будет иметь некоторое время ... после этого он автоматически перейдет в состояние готовности ...


На мой взгляд, основное различие между обоими механизмами заключается в том, что sleep / interrupt - это самый простой способ обработки потоков, тогда как wait / notify - это абстракция, направленная на облегчение взаимодействия потоков. Это означает, что сон / прерывание может что-то сделать, но выполнить эту конкретную задачу сложнее.

Почему wait / notify больше подходит? Вот некоторые личные соображения:

  1. Он обеспечивает централизацию. Он позволяет координировать связь между группой потоков с одним общим объектом. Это значительно упрощает работу.

  2. Он обеспечивает синхронизацию. Потому что это заставляет программиста обернуть вызов для ожидания / уведомления в синхронизированном блоке.

  3. Он не зависит от происхождения и количества нитей. При таком подходе вы можете добавлять больше потоков произвольно без редактирования других потоков или отслеживания существующих. Если вы использовали sleep / interrupt, сначала вам нужно будет сохранить ссылки на спящие потоки, а затем прервать их один за другим, вручную.

Пример из реальной жизни, который хорошо объясняет это, - это классический ресторан и метод, который персонал использует для общения между ними: официанты оставляют запросы клиентов в центральном месте (пробковая доска, стол и т. Д.), звоните в колокольчик, и рабочие с кухни приходят, чтобы взять такие просьбы. После того, как будет готов какой-нибудь курс, персонал кухни снова позвонит в колокольчик, чтобы официанты знали и отправляли их клиентам.


На странице документации оракула по методу wait()Object :

public final void wait()
  1. Заставляет текущий поток ждать, пока другой поток вызовет notify()метод или notifyAll()метод для этого объекта. Другими словами, этот метод ведет себя точно так, как если бы он просто выполнял вызов wait(0).
  2. Текущий поток должен владеть монитором этого объекта. Поток освобождает владельца этого монитора и ждет, пока другой поток не будет уведомлять потоки, ожидающие на мониторе этого объекта, просыпаться
  3. возможны прерывания и ложные пробуждения
  4. Этот метод должен вызываться только потоком, который является владельцем монитора этого объекта

Этот метод бросает

  1. IllegalMonitorStateException - если текущий поток не является владельцем монитора объекта.

  2. InterruptedException- если какой-либо поток прерывал текущий поток до или в то время, когда текущий поток ожидал уведомления. Прерванный статус текущего потока очищается при вызове этого исключения.

На странице документации оракула по методу sleep()Thread класса:

public static void sleep(long millis)
  1. Заставляет текущий исполняемый поток спать (временно прекратить выполнение) за указанное количество миллисекунд, с учетом точности и точности системных таймеров и планировщиков.
  2. Нить не теряет права собственности на какие-либо мониторы.

Этот метод бросает:

  1. IllegalArgumentException - если значение миллиса отрицательно

  2. InterruptedException- если какой-либо поток прервал текущий поток. Прерванный статус текущего потока очищается при вызове этого исключения.

Другое ключевое различие:

wait()это нестатический метод (метод экземпляра), в отличие от статического метода sleep()(метод класса).





java-threads