«Эта ошибка может возникнуть, если локальная сетевая система прерывает соединение, например, когда WinSock закрывает установленное соединение после сбоя повторной передачи данных (приемник никогда не подтверждает данные, отправленные в гнездо потока данных).». См. эту статью MSDN . См. Также Некоторая информация о «Программе вызвана отключением соединения» .
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(); }
}
Вы правы - Sleep () приводит к тому, что этот поток «спит», и ЦП отключается и обрабатывает другие потоки (иначе называемое переключением контекста), тогда как я считаю, что Wait заставляет ЦП обрабатывать текущий поток.
У нас есть и то, и другое, потому что, хотя может показаться разумным позволить другим людям использовать ЦП, пока вы его не используете, на самом деле есть накладные расходы на переключение контекста - в зависимости от того, как долго длится спящий режим, он может быть более дорогостоящим в циклах ЦП для переключения потоков, чем простое бездействие вашего потока в течение нескольких мс.
Также обратите внимание, что спящий режим вызывает переключение контекста.
Также - в общем случае невозможно управлять переключением контекста - во время ожидания ОС может (и будет при более длительном ожидании) выбрать обработку других потоков.
Проще говоря, ожидание - это ожидание, пока какой-то другой поток не вызовет вас, тогда как сон - это «не выполнять следующий оператор» в течение определенного периода времени.
Более того, сон является статическим методом в классе потока и работает с потоком, тогда как wait () находится в классе Object и вызывается для объекта.
Другой момент, когда вы вызываете wait для некоторого объекта, задействованный поток синхронизирует объект, а затем ждет. :)
Ожидание и сон - это две разные вещи:
sleep ()
поток перестает работать в течение указанного времени. wait ()
поток прекращает работу до тех пор, пока ожидающий объект не будет уведомлен, как правило, другими потоками. wait
и sleep
методы очень разные:
sleep
не имеет способа «проснуться», wait
имеет способ "пробуждения" во время периода ожидания другим потоком, вызывающим notify
или notifyAll
. Подумайте об этом, имена сбивают с толку в этом отношении; однако sleep
- стандартное имя, а wait
похоже на WaitForSingleObject
или WaitForMultipleObject
в Win API.
Одно ключевое отличие, о котором еще не упоминалось, заключается в том, что во время сна поток не снимает удерживаемые им блокировки, в то время как ожидание снимает блокировку с объекта, который wait ( )
вызывается.
synchronized(LOCK) {
Thread.sleep(1000); // LOCK is held
}
synchronized(LOCK) {
LOCK.wait(); // LOCK is not held
}