-1

I am trying to figure out why I am getting two lines printed with each iteration of the while loop when I run this code:

public void run() {
    long currentTime = System.nanoTime();
    long targetFPS = 1000;
    long delta;
    while(GameConstants.running) {
        delta = System.nanoTime() - currentTime;
        if(delta/1000000000 >= 1) {
            System.out.println(delta);
            currentTime = System.nanoTime();
        }
    }
}

I tried to adjust the code to just call System.out.println() once to debug, however it is still printing twice. I can't seem to figure out why this is happening since in this modified version, System.out.println(delta) is called, then printed is set to true so System.out.println(delta) should not be called again.

public void run() {
    long currentTime = System.nanoTime();
    long targetFPS = 1000;
    long delta;
            boolean printed = false;
    while(GameConstants.running) {
        delta = System.nanoTime() - currentTime;
        if(delta/1000000000 >= 1 & !printed) {
            System.out.println(delta);
            currentTime = System.nanoTime();
                            printed = true;
        }
    }
}

Code for context:

public class Game extends Canvas implements Runnable, KeyListener {

    private Thread gameThread;

public synchronized void start() {
    if(GameConstants.running) return;
    GameConstants.running = true;
    gameThread = new Thread(this);
    gameThread.start();
}

public synchronized void stop() {
    if(!GameConstants.running) return;
    GameConstants.running = false;
    try {
        gameThread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public void run() {
    long currentTime = System.nanoTime();
    long targetFPS = 1000;
    long delta;
            boolean printed = false;
    while(GameConstants.running) {
        delta = System.nanoTime() - currentTime;
        if(delta/1000000000 >= 1 && !printed) {
            System.out.println(delta);
            currentTime = System.nanoTime();
                            printed = true;
        }
    }
}

public void update() {
    if(GameConstants.gameState == 1 && !GameConstants.trialTypeDetermined ) {
        Random r = new Random();
        double prob = r.nextDouble();
        if(prob < GameConstants.goProb) {
            GameConstants.skipBad = true;
        }
        GameConstants.trialTypeDetermined = true;
        System.out.println(GameConstants.skipBad);
    }
      taskTimer(GameConstants.goTaskTimes.get(getGameState(GameConstants.gameState)));
    System.out.println(GameConstants.gameState);
    try {
        Thread.sleep(1);
    } catch(InterruptedException e) {
    }
}

public void render() {

}

//
public String getGameState(int gameState){
    return GameConstants.gameStates[GameConstants.gameState];
}

private void skipBad() {
    Random r = new Random();
    double prob = r.nextDouble();
    if(prob < GameConstants.goProb) {
        GameConstants.skipBad = true;
    }
    GameConstants.trialTypeDetermined = true;
}

public void taskTimer(long taskTime) {
    if(System.currentTimeMillis() - GameConstants.startTime >= taskTime) {
        GameConstants.taskComplete = true;
        GameConstants.startTime = System.currentTimeMillis();
        nextGameState();
        GameConstants.keyPressed = false;
    }
}

private void nextGameState() {
    if(GameConstants.gameState == 2 & GameConstants.skipBad) {
        GameConstants.gameState = GameConstants.gameState + 2;
    } else if(GameConstants.gameState != 5) {
        GameConstants.gameState++;
    } else {
        GameConstants.gameState = 1;
    }
    GameConstants.gameStateRegistered = false;
}

private void resetParameters() {

}

private void checkHit() {

}

public void keyPressed(KeyEvent e){
    int keyCode = e.getKeyCode();

    if(keyCode == KeyEvent.VK_SPACE && !GameConstants.keyPressed){
       GameConstants.keyPressed = true;
       if(!GameConstants.reached){
           GameConstants.reached = true;
           GameConstants.RT = System.currentTimeMillis();
       }
    }
}

public void keyReleased(KeyEvent e){

}

public void keyTyped(KeyEvent e){

}

public static void main(String[] args) {
    Game game = new Game();
    game.setPreferredSize(new Dimension(GameConstants.WIDTH * GameConstants.SCALE, GameConstants.HEIGHT * GameConstants.SCALE));
    game.setMaximumSize(new Dimension(GameConstants.WIDTH * GameConstants.SCALE, GameConstants.HEIGHT * GameConstants.SCALE));
    game.setMinimumSize(new Dimension(GameConstants.WIDTH * GameConstants.SCALE, GameConstants.HEIGHT * GameConstants.SCALE));

    JFrame frame = new JFrame("Game");
    frame.setSize(GameConstants.WIDTH * GameConstants.SCALE, GameConstants.HEIGHT * GameConstants.SCALE);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.add(game);
    frame.setVisible(true);
    game.start();
    game.run();
}
}
M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • 3
    How is `run()` called? Are there multiple threads? Why do you use `&` instead of `&&`? It shouldn't cause any problems but it is interesting. – clcto Mar 24 '14 at 06:32
  • Why do you say it prints twice per iteration of the while() loop? Where are you counting / tracking iterations? – Mark Phillips Mar 24 '14 at 06:37
  • I'll respond once I figure out how to add code to comments, I can't add the code in an answer because I am a new user. – user3454181 Mar 24 '14 at 06:41
  • The *question*. Not an answer. – clcto Mar 24 '14 at 06:43
  • Why is this question still open ? It has been correctly answered in both answers below, you should close it. – Aditya T Feb 09 '17 at 07:05

2 Answers2

4

Your bootstrap code is flawed you are calling both start and run effectively running the code twice. Remove the call to run.

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • Ah, ok, this seemed to fix the problem. I thought I also had to call run as well since I did not call it elsewhere. Thank you so much! – user3454181 Mar 24 '14 at 06:51
  • 2
    Your `start` method creates a `Thread` and also starts it. That thread is already going to call the `run` method. – M. Deinum Mar 24 '14 at 06:52
1

You have started multiple thread on the same object, You should use synchronized block to run thread-safe code,

synchronized(this){

long currentTime = System.nanoTime();
long targetFPS = 1000;
long delta;
while(GameConstants.running) {
    delta = System.nanoTime() - currentTime;
    if(delta/1000000000 >= 1) {
        System.out.println(delta);
        currentTime = System.nanoTime();
    }
}
}

After Updating Source Code

Yeah! here, you are calling run() method and start both...

game.start();
game.run();

remove calling run method explicitly, you will get desired result :)

Akhilesh Dhar Dubey
  • 2,152
  • 2
  • 25
  • 39