我创建了一个类来控制程序运行的速度,有点像垂直同步,它在每一帧向程序传递一些必要的信息。我的整个工作正常,但我尝试使用更准确的 Thread.sleep(long millis, int nanos),这是我使用起来相当缺乏经验的东西。根据我所看到的描述,它只是将提供的毫秒数添加到纳秒数,然后暂停线程。但是,大约 90% 的帧抛出一个奇怪的异常,我真的无法破译。
java.lang.IllegalArgumentException: nanosecond timeout value out of range
以下是我使用的大部分代码,它们以任何方式与我用来延迟线程的变量进行交互。
long startTime = System.nanoTime();
while (! this.stop)
{
try
{
// Run Frame
long endTime, deltaTime, deltaRemainder;
endTime = System.nanoTime();
deltaTime = endTime - startTime;
deltaRemainder = this.rate - (deltaTime % this.rate);
System.out.println("Frame Completed with "
+ (double)(deltaRemainder * .000000001) + " seconds left!");
if (deltaRemainder > 0)
Thread.sleep(0, (int)(deltaRemainder));
startTime = System.nanoTime();
}
catch (Exception e)
{
e.printStackTrace();
}
}
rate 是一个变量,它等于一个帧的长度(以纳秒为单位),stop 确实不重要,而且很明显。 start/endTime 是帧开始和结束的时间。 deltaTime 是帧完成所用的时间长度。最后,deltaRemainder 是帧应该花费的额外时间来完成(如果它花费的时间比它应该花费的时间长,它会跳到下一个可能的帧结束)。
谁能解释为什么抛出这个异常?我真的更愿意使用此函数提供的准确性。
最佳答案
您的 deltaRemainder 似乎超出了 0 到 999999 之间的允许范围。
来自 Thread.sleep 文档:
- millis - 以毫秒为单位的 hibernate 时间长度。
- nanos - 额外 0-999999 纳秒 hibernate 。
因此您应该检查它是否大于 999999,如果是,则将大于 999999 的值放入毫秒,例如
int milliseconds = 0;
if ( deltaRemainder > 999999 ) {
milliseconds = deltaRemainder / 1000000;
deltaRemainder = deltaRemainder % 1000000;
}
if ( milliseocnds > 0 || deltaRemainder > 0) {
Thread.sleep(milliseconds, deltaRemainder);
}
编辑:我的示例代码将被视为“深夜代码”,其中有错误;)。
关于Java Thread.sleep 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4281668/