0
\$\begingroup\$

I was working on my game loop and I came across an odd problem. The loop was working fine, my states could render, received updates, etc. I then proceeded to create my Input system, which, also works. However, after implementing that I continually & randomly receive a Exception in my thread stating: Exception in thread "Thread-3" java.lang.IllegalArgumentException: timeout value is negative

I first tried to debug this. The problem is there is 0 consistency with the exception occurring. KeyEvents seem to have no affect, due to the fact I can use the poll system & not generate an exception. That & sometimes upon running it automatically throws an exception. I've re-looked through the code and I'm not quite sure what is causing this.

For convenience I'll just leave the relevant code.

public class Game implements Runnable {

public int FPS = 0;

private Double delta;
private long lastFps = 0;

private final int TARGET = 60;
private final long OPTIMAL_TIME = 1000000000 / TARGET;   
private boolean gameRunning = false;

@Override
public void run() {

    long lastLoop = System.nanoTime();

    while (gameRunning){

        //Figure out how long its been since last update - used for entity calculation
        long current = System.nanoTime();
        long updateTime = current - lastLoop;
        lastLoop = current;

        delta = updateTime / ((double)OPTIMAL_TIME);

        lastFps += updateTime;
        FPS++;

        if(lastFps >= 1000000000){
            System.out.println("(FPS: "+ FPS +")");
            lastFps = 0;
            FPS = 0;
        }

        //Updates state + calls render
        updateState();

        /*
         * We need each frame to take 10mill-sec
         * Take recorded time + 10 milli
         * then factor current time
         * this ^ is final value to wait
         */
        try{
            Thread.sleep( (lastLoop - System.nanoTime() + OPTIMAL_TIME) /1000000 );
        }
        catch(InterruptedException exception){
            exception.printStackTrace();
        }



    }

}

Unless the KeyEvent's could possibly have relation to the problem or my input polling (Which doesn't manage time or anything affecting the thread) I'm not sure if it's needed to post any relevant code from that class. (If you think I need to you're welcome to ask but it's just boolean arrays + a string cache).

The question: Why is the thread encountering a negative timeout value?

\$\endgroup\$
3
  • \$\begingroup\$ Why are you using nano-scale time? Isn't micro-scale time good enough? \$\endgroup\$ Aug 23 '12 at 6:51
  • \$\begingroup\$ From my own practice/reading I was more used to using Nano scale. Does it make a big difference/should I change it? \$\endgroup\$ Aug 23 '12 at 7:05
  • \$\begingroup\$ The documentation for Java 6 says that it provides nano-scale precision, but does not guarantee nano-scale accuracy. The documentation for currentTimeMillis() also mentions that some OSes only measure time in 10 millionths of a second. \$\endgroup\$ Aug 23 '12 at 18:12
1
\$\begingroup\$

Your problem is in the line that performs the sleep operation:

Thread.sleep( (lastLoop - System.nanoTime() + OPTIMAL_TIME) /1000000 );

Remember that System.nanoTime() will almost always be after the last-recorded time stored in lastLoop, so you need to reverse those two expressions.

\$\endgroup\$
1
  • \$\begingroup\$ Ah forgot about that. However I was a little curious & looked in to the problem more, turns out it was a "rounding" problem, or appeared to be. Which made it have negative numbers. Using Micro-Time has solved the problem, so I do not think I do this. \$\endgroup\$ Aug 24 '12 at 1:00
1
\$\begingroup\$

Okay fixed the problem. As suggested by a friend + comment I should be using MicroTime which has appeared to solve the problem. For anyone looking for how I solved it, I just changed these 2 lines to this:

long current = System.currentTimeMillis();

Thread.sleep( (lastLoop - System.currentTimeMillis() + OPTIMAL_TIME) /1000000 );
\$\endgroup\$
1
  • \$\begingroup\$ It won't let me accept my own answer so I was waiting for this time limit to expire. Doesn't matter I guess, the other answer also works so I just marked that one. \$\endgroup\$ Aug 24 '12 at 13:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.