Java 简单时钟应用程序的精确线程睡眠?
我有一个简单的时钟线程,每秒更新一次时间。为了实现这一点,我使用了Java 简单时钟应用程序的精确线程睡眠?,java,multithreading,concurrency,Java,Multithreading,Concurrency,我有一个简单的时钟线程,每秒更新一次时间。为了实现这一点,我使用了Thread.sleep(1000)每1秒调用一次worker类。然而,时钟似乎比我的计算机时钟运行得稍快。有没有办法使睡眠时钟正常化,使它能在一秒钟内完全醒来,与我的计算机时钟一样?根据 导致当前正在执行的线程休眠(暂时停止 执行),以指定的毫秒数为准 系统计时器和调度程序的精度和准确性。线 不会失去任何监视器的所有权 你可以做的是少睡,比如说400毫秒,然后检查时间是否改变 或者,您可以每秒使用一次和一次触发事件,并更新您的时
Thread.sleep(1000)
每1秒调用一次worker类。然而,时钟似乎比我的计算机时钟运行得稍快。有没有办法使睡眠时钟正常化,使它能在一秒钟内完全醒来,与我的计算机时钟一样?根据
导致当前正在执行的线程休眠(暂时停止
执行),以指定的毫秒数为准
系统计时器和调度程序的精度和准确性。线
不会失去任何监视器的所有权
你可以做的是少睡,比如说400毫秒,然后检查时间是否改变
或者,您可以每秒使用一次和一次触发事件,并更新您的时间
编辑:根据您的评论,您可以这样做:
long initTime = System.getTimeinMillis();
while(true)
{
Thread.sleep(200);
if((System.getTimeInMillis() - initTime) >= 1000)
{
initTime = System.getTimeInMillis();
//Update your timer.
}
}
这个想法是去睡觉,醒来(可能是过早的),并再次检查时间去睡觉 在系统负载较重的情况下,计时器线程不会得到调度,线程可能不会从睡眠中醒来,从而导致时钟超时 但只要有可能,总是要显示正确的时间 一般建议:最大化睡眠以保持最少唤醒(每次唤醒涉及一个上下文切换) 以下是我为自己写的东西:
/**
* Put the calling thread to sleep.
* Note, this thread does not throw interrupted exception,
* and will not return until the thread has slept for provided time.
*
* @param milliSecond milliSecond time to sleep in millisecond
*/
public static void sleepForcefully(int milliSecond) {
final long endingTime = System.currentTimeMillis() + milliSecond;
long remainingTime = milliSecond;
while (remainingTime > 0) {
try {
Thread.sleep(remainingTime);
} catch (InterruptedException ignore) {
}
remainingTime = endingTime - System.currentTimeMillis();
}
}
这种类型的逻辑在JDK和其他地方的计时器、pinger等上都使用。您是否使用System.currentTimeMillies()来执行?无法保证它不会比您的计算机运行得慢(在负载下)你不能依赖
睡眠
来保证准确性。除非你是在实时操作系统上运行。不久前,我看到了一个简单的修复方法,每次它醒来时都检查currentTimeMillies(),并且有一个不同的睡眠时间。但我再也找不到这个例子了?@Yonk:我已经更新了我的回答。这类似于我的第一个建议。@Yonk请记住,即使是currentTimeMillies()
也不总是100%准确。我不会用这样的循环来绕开这个问题:如果睡眠1000毫秒不准确,那么睡眠200毫秒也不太可能准确。现在您已经多次引入该错误…@StevenSchlansker:这就是为什么我建议使用计时器的原因。