我想创建一个基本上像普通时钟一样工作的MIDI时钟。它只是勾选并计算其刻度。现在我已经阅读了很多次Thread.sleep()
根本不准确。因此,每隔几个周期校正一次,确保它长期稳定吗?
我的时钟课
public class Clock implements Runnable {
long beatsPassed = 0;
double bpm = 120; // default
double beatLength; // default
boolean running = false;
Clock(int bpm) {
this.bpm = bpm;
this.beatLength = 60.0 / bpm;
this.running = true;
}
public void run() {
int beatLengthInMS = (int) (this.beatLength * 1000);
long baseTime = System.currentTimeMillis();
// long corrected = 1;
try {
while (running) {
// check delay every 9 beats
// mod == 0 lets it the first time through which causes a negative timeout
if (this.beatsPassed % 10 == 9) {
// corrected = (System.currentTimeMillis() - baseTime) - (beatLengthInMS * 9);
Thread.sleep(beatLengthInMS + ((System.currentTimeMillis() - baseTime) - (beatLengthInMS * 9)));
baseTime = System.currentTimeMillis();
} else {
Thread.sleep(beatLengthInMS);
}
this.beatsPassed++;
// System.out.println(corrected);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
现在我已经测量了相当稳定的时间。它总是增加约6-9毫秒。 我忘了一些基本的东西还是我的方法错了?如果你能告诉我一个更高效的方式,这也很棒吗?
答案 0 :(得分:1)
最简单的方法(除了使用Timer,在JDK中有两个AFAIK)是一种方法
void sleepUntil(long absoluteTime) throw InterruptedException {
while (true) {
long now = System.currentTimeMillis();
if (now >= absoluteTime) break;
Thread.sleep(absoluteTime - now);
}
}
使用循环是因为虚假的唤醒(在实践中可能永远不会发生,但比抱歉更安全)。预先计算absoluteTime
(基本上,你只看一开始的当前时间)。