Как Thread.sleep() работает внутри

#java #multithreading #concurrency

#java #многопоточность #параллелизм

Вопрос:

Допустим, у меня есть поток T, и он содержит один ресурс R. Если я вызову Thread.sleep() в текущем потоке, то есть, освободит ли он ресурс R (чтобы позволить другим потокам использовать его) перед переходом в спящий режим или нет? Или он будет удерживать этот ресурс и снова, когда он проснется, он будет использовать ресурс R и после завершения работы освободит его?

Комментарии:

1. можете ли вы более конкретно рассказать о своем примере ресурса

2. В общем, нет. При переходе в спящий режим ресурсы не освобождаются.

3. @JigarJoshi, обычно я бы задал тот же вопрос, но поскольку я знаю, что sleep() ничего не закрывает и не освобождает , в данном случае это не имеет большого значения. Все, что программисту нужно знать о sleep(n), это то, что он будет блокировать вызывающего абонента до тех пор, пока не произойдет прерывание или не пройдет n миллисекунд (в зависимости от того, что наступит раньше). Он не делает ничего другого, кроме этого.


Ответ №1:

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

Итак, когда вы вызываете метод sleep(), поток покидает процессор и останавливает его выполнение на некоторое время. В течение этого времени он не потребляет процессорное время, поэтому процессор может выполнять другие задачи.Когда поток находится в спящем режиме и прерывается, метод немедленно выдает исключение InterruptedException и не ждет, пока закончится время ожидания.

Java concurrency API имеет другой метод, который заставляет объект потока покидать процессор. Это метод yield(), который указывает JVM, что объект Thread может покинуть процессор для других задач. JVM не гарантирует, что он выполнит этот запрос. Обычно он используется только для целей отладки.

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

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

Ответ №2:

Из этой статьи Javamex:

Метод Thread.sleep() эффективно «приостанавливает» текущий поток на определенный период времени. Мы использовали его в нашем самом первом примере с потоками, чтобы заставить потоки периодически отображать сообщение, переходя в режим ожидания между сообщениями. С самого начала важно помнить о следующем:

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

Ответ №3:

Поток, который переходит в спящий режим, будет удерживать блокировку (not release resource) , пока он спит. Спящий поток даже не будет запланирован на время его сна (или до тех пор, пока он не будет прерван, а затем он проснется)

Ответ №4:

Если ваш ресурс R является java monitor, то есть только два способа его освобождения:

  • synchronized блок выхода
  • вызов wait на собственном мониторе

Ответ №5:

Javadoc говорит — sleep() : Переводит текущий выполняющийся поток в спящий режим (временно прекращает выполнение) на указанное количество миллисекунд, в зависимости от точности и точности системных таймеров и планировщиков

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

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

Если текущий поток заблокирован при вызове wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int) , methods of Thread class , то его статус прерывания будет очищен, и он получит исключение InterruptedException .