我记录了一个事件流(例如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 的准确性来交换我给出的两个例子之间的某个地方?