Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:时间漂移_Java_Datetime_Scheduling - Fatal编程技术网

Java:时间漂移

Java:时间漂移,java,datetime,scheduling,Java,Datetime,Scheduling,我有一个类,它就像过去某个时间的时钟,可以以不同的速度播放。在我下面的示例代码中,我以60x的速度回放 我注意到时间每10秒漂移一秒左右,我想知道如何处理它 import java.util.Calendar; public class Clock { long delta; long lastCalledTime; long startingTime; private float speed = 1f; public synchronized lo

我有一个类,它就像过去某个时间的时钟,可以以不同的速度播放。在我下面的示例代码中,我以60x的速度回放

我注意到时间每10秒漂移一秒左右,我想知道如何处理它

import java.util.Calendar;

public class Clock {

    long delta;
    long lastCalledTime;
    long startingTime;
    private float speed = 1f;

    public synchronized long getAdjustedTimeMillis() {
        long time = (System.currentTimeMillis() - (delta));
        long val = (startingTime + (long) ((time - lastCalledTime) * speed));
        return val;
    }

    public synchronized void setPlaybackSpeedFromTime(float speed, long startingTime) {
        this.startingTime = startingTime;
        this.delta = System.currentTimeMillis() - startingTime;
        this.speed = speed;
        this.lastCalledTime = System.currentTimeMillis() - delta;
    }

    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(2010, 4, 4, 4, 4, 4);
        Clock clock = new Clock();
        clock.setPlaybackSpeedFromTime(60f, calendar.getTimeInMillis());
        for (int i = 0; i < 1000; i++) {
            calendar.setTimeInMillis(clock.getAdjustedTimeMillis());
            System.out.println(calendar.getTime());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }


    }

}
正如你所看到的,“秒”漂移。我想要的是:

Tue May 04 04:04:04 PDT 2010
Tue May 04 04:05:04 PDT 2010
Tue May 04 04:06:04 PDT 2010
Tue May 04 04:07:04 PDT 2010
Tue May 04 04:08:04 PDT 2010
Tue May 04 04:09:04 PDT 2010
Tue May 04 04:10:04 PDT 2010
Tue May 04 04:11:04 PDT 2010
Tue May 04 04:12:04 PDT 2010
Tue May 04 04:13:04 PDT 2010
Tue May 04 04:14:04 PDT 2010
Tue May 04 04:15:04 PDT 2010
Tue May 04 04:16:04 PDT 2010
Tue May 04 04:17:04 PDT 2010
Tue May 04 04:18:04 PDT 2010
Tue May 04 04:19:04 PDT 2010
Tue May 04 04:20:04 PDT 2010
Tue May 04 04:21:04 PDT 2010
Tue May 04 04:22:04 PDT 2010
Tue May 04 04:23:04 PDT 2010
Tue May 04 04:24:04 PDT 2010

为什么不直接使用系统时钟呢

initialStartTime = System.currentTimeMillis();
while (true){
    if (intialStartTime - System.currentTimeMillis() % 1000 == 0){
        System.out.println(calendar.getTime());
    }
}

显然,您希望在后台线程上运行上述内容,而不是在while(true)中使用一些合理的退出条件。有大量关于线程等的信息。

只需根据您知道的准确来源确定您的时间。。。对于临时应用,系统时钟通常足够好。如果你试图让你的应用程序占时间,那么你的精确度将受到JVM并发健壮性的限制。而且,老实说,这不是JVM想要做好的事情。

您有时间漂移,因为当您的进程处理其他操作时,已经过了一段时间。不要使用
Thread.sleep(int)
,而是尝试
java.util.Timer.scheduleAtFixedRate(任务、日期、期间)
。计时器在内部计算下一个执行时间,并在指定时间触发。该触发也由定时器使用等待通知锁定机制在内部完成。简而言之,您必须实现TimerTask来更新您的时钟,然后使用计时器以所需的间隔(例如1000毫秒)安排任务。

好吧,问题很简单-Thread.sleep不是一个精确的函数,而且您也没有考虑处理时间,这将在多次(多次)迭代中累积。不知道如何解决这个问题,但这是否保证在ms上每1000毫秒执行一次?或者只是在球场上得到一些东西?没有保证,计时器可能会“失火”(错过触发时间)。这通常发生在线程数量较多且线程池较小的环境中。在通常情况下,计时是非常准确的。事实上,Java是为常见的业务应用而构建的,而不是为关键计时应用而构建的。然而,也有人试图构建专门的实现。
initialStartTime = System.currentTimeMillis();
while (true){
    if (intialStartTime - System.currentTimeMillis() % 1000 == 0){
        System.out.println(calendar.getTime());
    }
}