Чтобы текущий поток оставался на заданное время ожидания, я могу использовать:
LockSupport.parkNanos(long nanos);
or
Thread.sleep(long millis);//internally same as Object.wait(long) i guess.
К сожалению, все внутренние тики этих двух методов основаны на системных часах.
Если системные часы изменяются (с помощью ntptime или вручную) во время периода ожидания, этот метод не будет действовать должным образом.
например, в t0 я вызываю этот метод, например Thread.sleep (dt), чтобы засыпать dt секунд. Во время периода ожидания я устанавливаю свои системные часы на 20 секунд вперед, затем поток будет спать фактически dt + 20 секунд.
используйте следующий код, чтобы проверить это:
public static void main(String[] args) throws InterruptedException {
long s = System.nanoTime();
int _10sec = 10 * 1000;
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(_10sec));
//or Thread.sleep(_10sec);
long e = System.nanoTime();
long used = e - s;
System.out.println("Used:" + TimeUnit.NANOSECONDS.toMillis(used)); }
используйте что-то вроде «date && sudo date -s 16:10:40», чтобы установить системные часы вперед на несколько минут во время ожидания, и вы увидите, что произошло на выходе.
Это печально, потому что в моем продукте многие вещи основаны на системных часах,
например, Scheduler (вызывающий наконец LockSupport.park) для проверки пульса через соединение Socket.
Если системные часы были переведены вперед дольше, чем время ожидания, планировщик посчитает, что время ожидания истекло, но на самом деле это не так.
Кто-нибудь сталкивался с такой же проблемой, и как ее решить?
ИЗМЕНИТЬ:
В моем продукте высокой доступности я использую Watchdog, чтобы убить ОС, когда большая нагрузка блокирует систему (так называемая стратегия самоубийства). Я должен кормить собаку изнутри, чтобы предотвратить нежелательное самоубийство , Использование ThreadSupport.parkNanos (xxx) приведет к неожиданному самоубийству