java - 有什么方法可以基于自由运行、独立于系统时钟的时钟来停放线程吗?

标签 java timer scheduler thread-sleep system-clock

要使当前线程停放指定的超时时间,我可以使用:

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/

相关文章:

java - 带填充的矩形圆交点

java - 如何在 Java 中比较字符串?

android - ProgressDialog Box虚拟计时器

Java显示当前时间

java - 在通话期间停止重复闹钟

Java环境变量的问题,maven也是

iphone - 应用程序空闲超时 - 想要在特定的空闲间隔内实现自动锁定

linux - cron 如何在内部安排作业?

每天特定时间的 MySQL 事件调度程序

python - web2py 计划任务重新创建(重置)数据库