我有一个简单的时钟线程,每秒更新一次。为了实现这一点,我使用Thread.sleep(1000)
每1秒调用一次工作类,但是,时钟似乎比我的计算机时钟稍微快一点。有没有办法使睡眠时钟正常化,以便它能在一秒钟内完全唤醒,与我的电脑时钟相同?
答案 0 :(得分:2)
根据JavaDoc:
,这应该是预料之中的导致当前正在执行的线程进入休眠状态(暂时停止 执行)指定的毫秒数,受制于 系统定时器和调度程序的精度和准确性。线程 不会失去任何监视器的所有权。
你能做什么,可能是睡得少,比如400毫秒,然后检查时间是否有所改变。
或者,您可以使用Timer
并每秒触发一次事件并更新您的时间。
编辑:根据您的评论,您可以这样做:
long initTime = System.getTimeinMillis();
while(true)
{
Thread.sleep(200);
if((System.getTimeInMillis() - initTime) >= 1000)
{
initTime = System.getTimeInMillis();
//Update your timer.
}
}
答案 1 :(得分:0)
想法是睡觉,醒来(可能过早)并再次检查时间进入睡眠状态。
在系统负载过重的情况下,您的计时器线程不会被调度,并且线程可能无法从睡眠状态唤醒,从而导致时钟停止运行。
但它总是在尽可能显示正确的时间。
一般建议:最大化睡眠以使唤醒最小化(每次唤醒都涉及一次上下文切换)。
这是我为自己写的东西:
/**
* 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和其他地方的所有定时器,pingers等中使用。