23

我需要将 while 循环暂停特定的毫秒数。我曾尝试使用 Thread.sleep(duration) 但它不准确,尤其是在循环场景中。毫秒精度在我的程序中很重要。

这是我不想回去检查条件的算法,直到expectedElapsedTime经过。

while (condition) {
    time = System.currentTimeMillis();
    //do something
    if (elapsedTime(time) < expectedElapsedTime) ) {
        pause the loop  // NEED SUBSTITUTE FOR Thread.sleep()
    }
    // Alternative that I have tried but not giving good results is 
    while ((elapsedTime(time) < expectedElapsedTime)) {
        //do nothing
    }
}

long elapsedTime(long time) {
   long diff = System.currentTimeMillis() - time;
   return diff;
}
4

7 回答 7

12

尝试ScheduledThreadPoolExecutor。它应该提供更可靠的计时结果。

于 2012-02-04T19:39:34.423 回答
10

你能指望什么?

如果您进入睡眠状态,那么一旦您的进程再次可运行,它将不得不等待线程调度程序再次对其进行调度。

我的意思是,如果你睡 50 秒,这并不意味着你的进程将在 50 秒内运行。因为它会唤醒并且可以运行,所以它必须等待被调度到 CPU,这需要额外的时间加上你的时间有上下文切换。

您无法控制它,因此您无法获得您所说的准确性。

对于您的情况,我建议改为使用旋转循环。

long now = System.currentTimeMillis();   
while(now < expectedElapsedTime){
    now = System.currentTimeMillis();
}
于 2012-02-04T19:26:16.590 回答
7

Java 不是一个实时系统,你不能让一个线程在如此紧张的时间里离开并回来。要将程序执行时间安排到毫秒,您需要使用不同的平台,例如simpleRTJJava 实时扩展

于 2012-09-17T20:34:18.063 回答
2

延迟很可能是任意选择的,所以我会质疑您是否需要实时间隔计时。

如果您需要阅读时间,您需要忙于等待时间到达。放弃 CPU 意味着你不能保证你会在你想要的时候把它拿回来。

于 2012-02-04T19:47:47.697 回答
1

解决方案是使用可运行的处理程序并使用“postDelayed”方法。例子:

new Handler().postDelayed(new Runnable() {
public void run () {
    // Do delayed stuff!
}
}, 5000L); //5 seconds delay 

https://stackoverflow.com/a/21680858

于 2014-12-13T18:09:18.577 回答
1

如果你想要准确的声音,你可以使用音序器并在 BPM 中设置速度:sequencer.setTempoInBPM(120);

于 2014-03-03T20:05:15.803 回答
1

您可以实现等待/通知机制,并将通知处于等待状态的另一个线程的责任委托给另一个线程,该时间量已经过去并且它可以继续......

例如,当 threadA 需要等待一定时间时,您可以将线程置于等待状态并启动计时器任务,在一定时间(间隔)后调用 notify 并唤醒继续前进的 ThreadA,这可以做个替代品。

于 2012-02-04T19:29:25.037 回答