1

我记录了一个事件流(例如ArrayList<InputEvent>按 排序InputEvent.getWhen())。连续事件之间的时间差异可以是几十毫秒的数量级。

我的目标是尽可能准确地执行(“重播”)记录的流,即在 执行第一个事件,InputEvent firstEvent在执行long startTime = System.currentTimeMillis()第二个事件startTime + (secondEvent.getWhen() - firstEvent.getWhen()),依此类推。

当然,最准确的方法是:

execute(ArrayList<InputEvent> stream) {
    long startTime = System.currentTimeMillis();
    long firstTime = stream.get(0).getWhen();
    for (InputEvent e : stream) {
        while System.currentTimeMillis() < 
                startTime + e.getWhen() - firstTime) {  }
        executeEvent(e);
    }
}

另一方面,这是一种非常消耗 CPU 的方法:

execute(ArrayList<InputEvent> stream) {
    long lastWhen = strem.get(0).getWhen();
    for (InputEvent e : stream) {
        try {
            Thread.sleep(e.getWhen() - lastWhen);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
        executeEvent(e);
        lastWhen = e.getWhen();
    }
}

CPU 更好,但“取决于系统计时器和调度程序的精度和准确性”(http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#sleep(长))。

我也考虑过 TimerTaskExecutor 但我认为它也使用 Thread.sleep 并且遇到同样的主观问题。

问题是 - 我是否应该担心系统相关的准确性会导致流的意外流动?有没有办法用 CPU 的准确性来交换我给出的两个例子之间的某个地方?

4

0 回答 0