要使当前线程停放指定的超时时间,我可以使用:
LockSupport.parkNanos(long nanos);
或
Thread.sleep(long millis);//internally same as Object.wait(long) i guess.
不幸的是,这两种方法的内部滴答都是基于系统时钟的。
如果在等待期间系统时钟发生变化(通过ntptime或手动),这些方法将不会按预期工作。
例如,在 t0 中,我像 Thread.sleep(dt) 一样调用此方法来 hibernate dt 秒。 在等待期间,我将系统时钟提前20秒,然后线程实际上会 hibernate 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 连接进行心跳检查。
如果系统时钟向前设置的时间超过了超时时间,调度程序会认为它超时,但实际上并没有。
有没有人遇到同样的问题,怎么解决的?
编辑:
在我的 HA 产品中,当重负载阻塞系统时,我使用 Watchdog 来终止操作系统(所谓的自杀策略)。我必须给狗内喂以防意外自杀,使用ThreadSupport.parkNanos(xxx)会发生意外自杀
最佳答案
我要做的是定期唤醒 sleep ,例如每秒、5 秒或每分钟。如果你想要调整时间,它可以检查 currentTimeMillis() ,或者如果你想要单调递增的时间,它可以检查 nanoTime() 。
关于java - 有什么方法可以基于自由运行、独立于系统时钟的时钟来停放线程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15942668/