Разница между ожиданиями () и сном ()

«Эта ошибка может возникнуть, если локальная сетевая система прерывает соединение, например, когда WinSock закрывает установленное соединение после сбоя повторной передачи данных (приемник никогда не подтверждает данные, отправленные в гнездо потока данных).». См. эту статью MSDN . См. Также Некоторая информация о «Программе вызвана отключением соединения» .

1132
задан Vadim Kotov 27 July 2017 в 15:14
поделиться

6 ответов

A wait может быть «разбужен» другим потоком, вызывающим notify на мониторе, который ожидает, тогда как сна не может. Также ожидание уведомление ) должно происходить в блоке synchronized на объекте монитора, тогда как sleep не выполняется:

Object mon = ...;
synchronized (mon) {
    mon.wait();
} 

At в этот момент выполняющийся в данный момент поток ожидает и освобождает монитор . Другой поток может выполнить

synchronized (mon) { mon.notify(); }

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

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

Другой момент: вы вызываете wait на самом объекте (т.е. вы ждете на мониторе объекта), тогда как вы вызываете sleep на ] Thread .

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

synchronized {
    while (!condition) { mon.wait(); }
}
810
ответ дан 19 December 2019 в 20:14
поделиться

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

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

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

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

3
ответ дан 19 December 2019 в 20:14
поделиться

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

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

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

5
ответ дан 19 December 2019 в 20:14
поделиться

Ожидание и сон - это две разные вещи:

  • В sleep () поток перестает работать в течение указанного времени.
  • В wait () поток прекращает работу до тех пор, пока ожидающий объект не будет уведомлен, как правило, другими потоками.
14
ответ дан 19 December 2019 в 20:14
поделиться

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

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

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

6
ответ дан 19 December 2019 в 20:14
поделиться

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

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


synchronized(LOCK) {
    LOCK.wait(); // LOCK is not held
}
320
ответ дан 19 December 2019 в 20:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: