要使当前线程停在指定的超时时间,我可以使用:
LockSupport.parkNanos(long nanos);
或者
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”之类的东西在等待期间将系统时钟提前几分钟,你会从输出中看到发生了什么。
很遗憾,因为在我的产品中,很多东西都是基于系统时钟的,
例如调度程序(最终调用 LockSupport.park)通过 Socket 连接进行心跳检查。
如果系统时钟设置的时间比超时时间长,调度器会认为它超时,但实际上不是。
有没有人遇到过同样的问题,你是怎么解决的?
编辑:
在我的 HA 产品中,当重负载阻塞系统时,我使用 Watchdog 杀死操作系统(所谓的自杀策略)。我必须在内部喂狗以防止意外自杀,使用 ThreadSupport.parkNanos(xxx) 会有意外自杀