我创建了一个控制程序运行速度的类,有点像垂直同步,它会在每一帧向程序传递一些必要的信息。我有整个工作,但我已经尝试使用更准确的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是帧应该完成的额外时间量(如果它需要的时间超过它应该的时间,它会跳到最后一个可能的帧结束)。
有人可以解释为什么抛出这个异常吗?我更愿意使用此功能提供的准确性。
答案 0 :(得分:7)
您的deltaRemainder似乎超出了0到999999之间的允许范围。
来自Thread.sleep文档:
因此,您应该检查它是否大于999999,如果是,请将高于999999的值放入毫秒,例如
int milliseconds = 0;
if ( deltaRemainder > 999999 ) {
milliseconds = deltaRemainder / 1000000;
deltaRemainder = deltaRemainder % 1000000;
}
if ( milliseocnds > 0 || deltaRemainder > 0) {
Thread.sleep(milliseconds, deltaRemainder);
}
编辑:我的示例代码将被视为“深夜代码”,其中有错误;)。
答案 1 :(得分:0)
只有一个猜测:
整数有32位,所以整数从-2 ^ 31到2 ^ 31-1 如果deltaRemainder太大,它可能会溢出,结果int将为负数。 你的deltaRemainder可以超过2 ^ 31吗? (2GB是aprox 2.000.000.000,它是:2秒?)
其他猜测是:
deltaRemainder是> 0但是<所以int的值是0。