Как Java рассчитывает время сна, когда ПК переходит в режим гибернации?

Я написал Java-программу, которая выполняет некоторую функцию и, как ожидается, будет спать в течение 12 часов (через TimeUnit.HOURS.sleep(12) ), а затем продолжит выполнение другой функции.

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

Однако на данный момент прошло более 12 часов с тех пор, как была вызвана начальная TimeUnit.HOURS.sleep(12), а код (то есть вторая функция) не выполнился.

Означает ли это, что теперь мне нужно ждать еще 12 часов (начиная с того момента, когда я разбудил ноутбук), прежде чем он выполнит желаемый код? (Я не могу остановить свою программу прямо сейчас, чтобы проверить это, потому что тогда я гарантирую, что моя функция не будет выполняться даже после дополнительных 12 часов, поскольку она зависит от вывода первой функции, которая зависит от данных в реальном времени)

Я нашел аналогичную ветку на SO, связанную с C, но ничего о Java.

Основываясь на одном потоке, который я прочитал, программа сравнивает две метки времени при определении времени сна, но, конечно, этого не может быть, иначе мой код уже был бы выполнен. Так как же thread.sleep() работает под капотом?

Спасибо


person Alex K    schedule 18.10.2018    source источник
comment
Теоретически гибернация замораживает состояние диска, памяти и процессора и надежно сохраняет их. Это означает, что как только вы включите свой ноутбук после выхода из спящего режима, он возобновит работу с того места, где вы остановились. В течение этого периода времени в фоновом режиме не выполняется ни один процесс или поток.   -  person Arihant Bansal    schedule 18.10.2018


Ответы (1)


Thread.sleep реализация явно зависит от платформы.

HotSpot JVM вызывает WaitForMultipleObjects в Windows и pthread_cond_timedwait с CLOCK_MONOTONIC во всех операционных системах POSIX. Ни Windows, ни Linux API не учитывают время, когда система приостановлена.

По сути, Thread.sleep никогда не предназначался для работы в спящем режиме. Для получения дополнительной информации см. обсуждение JDK-8146730 и JDK-8146527.

person apangin    schedule 18.10.2018
comment
Я бы попробовал несколько раз спать в течение 1 минуты (или меньше), пока время не будет достигнуто на настенных часах. +1 - person Peter Lawrey; 18.10.2018
comment
Я только что попробовал это с Java 1.8.0_202 в Windows 10, и действительно, целевое время сна было пропущено примерно на столько же времени, сколько потребовалось, чтобы перевести компьютер в спящий режим, немного подождать и вывести его из спящего режима. - person Dreamspace President; 18.07.2019