Разница между ожиданиями () и сном () - PullRequest
1128 голосов
/ 24 июня 2009

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

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

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

Ответы [ 32 ]

3 голосов
/ 06 мая 2014

Различия между ожиданиями () и сном ()?

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

3 голосов
/ 23 сентября 2013

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

2 голосов
/ 13 мая 2016

Со страницы документации Oracle на wait () метод Object:

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

Этот метод выдает

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

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

Со страницы документации оракула на sleep () метод Thread class:

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

Этот метод выдает:

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

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

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

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

2 голосов
/ 20 декабря 2015

Должен вызываться из синхронизированного блока: wait() метод всегда вызывается из синхронизированного блока, т. Е. wait() метод должен блокировать монитор объекта перед объектом, для которого он вызывается. Но метод sleep() может быть вызван извне синхронизированного блока, т. Е. Метод sleep() не нуждается ни в каком объектном мониторе.

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

Принадлежит к какому классу: wait() метод относится к java.lang.Object классу, но sleep() метод относится к java.lang.Thread классу.

Вызывается для объекта или потока: wait() метод вызывается для объектов, но метод sleep() вызывается для потоков, а не объектов.

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

При вызове из синхронизированного блока: при вызове метода wait() поток покидает блокировку объекта. Но метод sleep() при вызове из синхронизированного блока или потока метода не оставляет объектную блокировку.

Подробнее Ссылка

2 голосов
/ 01 декабря 2014

Пример сна не снимает блокировку, а ожидание делает

Здесь есть два класса:

  1. Main : Содержит основной метод и два потока.
  2. Singleton : это одноэлементный класс с двумя статическими методами getInstance () и getInstance (логическое isWait).

    public class Main {
    
    private static Singleton singletonA = null;
    private static Singleton singletonB = null;
    
    public static void main(String[] args) throws InterruptedException {
    
    Thread threadA = new Thread() {
        @Override
        public void run() {
    
            singletonA = Singleton.getInstance(true);
    
        }
    };
    
    Thread threadB = new Thread() {
        @Override
        public void run() {
            singletonB = Singleton.getInstance();
    
            while (singletonA == null) {
                System.out.println("SingletonA still null");
            }
    
            if (singletonA == singletonB) {
                System.out.println("Both singleton are same");
            } else {
                System.out.println("Both singleton are not same");
            }
    
        }
    };
    
    threadA.start();
    threadB.start();
    
     }
    }
    

и

public class Singleton {

    private static Singleton _instance;

    public static Singleton getInstance() {

    if (_instance == null) {
        synchronized (Singleton.class) {
            if (_instance == null)
                _instance = new Singleton();
        }
    }
    return _instance;

}

public static Singleton getInstance(boolean isWait) {

    if (_instance == null) {
        synchronized (Singleton.class) {
            if (_instance == null) {
                if (isWait) {
                    try {
                        // Singleton.class.wait(500);//Using wait
                        Thread.sleep(500);// Using Sleep
                        System.out.println("_instance :"
                                + String.valueOf(_instance));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                _instance = new Singleton();
            }
        }
    }
    return _instance;

 }
}

Теперь, запустив этот пример, вы получите вывод ниже:

_instance :null
Both singleton are same

Здесь экземпляры Singleton, созданные threadA и threadB, одинаковы. Это означает, что threadB ожидает снаружи, пока threadA не снимет свою блокировку.

Теперь измените Singleton.java, комментируя Thread.sleep (500); метод и раскомментирование Singleton.class.wait (500); , Здесь из-за Singleton.class.wait (500); метод threadA снимет все блокировки получения и перейдет в состояние «Runnable», threadB получит изменение для входа в синхронизированный блок.

Теперь запустите снова:

SingletonA still null
SingletonA still null
SingletonA still null
_instance :com.omt.sleepwait.Singleton@10c042ab
SingletonA still null
SingletonA still null
SingletonA still null
Both singleton are not same

Здесь экземпляры Singleton, созданные threadA и threadB, НЕ одинаковы, потому что threadB получил изменение для входа в синхронизированный блок и через 500 миллисекунд threadA начал с последней позиции и создал еще один объект Singleton.

2 голосов
/ 30 января 2014

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

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

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

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

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

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

2 голосов
/ 15 июля 2013

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

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

1 голос
/ 11 мая 2013

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

1 голос
/ 09 сентября 2014

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

1 голос
/ 08 августа 2013

На самом деле, все это четко описано в документации Java (но я понял это только после прочтения ответов).

http://docs.oracle.com/javase/8/docs/api/index.html:

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

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

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