Java Thread.sleep异常

时间:2010-11-26 00:06:57

标签: java multithreading exception sleep

我创建了一个控制程序运行速度的类,有点像垂直同步,它会在每一帧向程序传递一些必要的信息。我有整个工作,但我已经尝试使用更准确的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是帧应该完成的额外时间量(如果它需要的时间超过它应该的时间,它会跳到最后一个可能的帧结束)。

有人可以解释为什么抛出这个异常吗?我更愿意使用此功能提供的准确性。

2 个答案:

答案 0 :(得分:7)

您的deltaRemainder似乎超出了0到999999之间的允许范围。

来自Thread.sleep文档:

  • millis - 以毫秒为单位的睡眠时间。
  • nanos - 0-999999额外纳秒睡眠。

因此,您应该检查它是否大于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。