Java System.out.println在while循环的每次迭代中打印两次

Java System.out.println在while循环的每次迭代中打印两次,java,game-loop,Java,Game Loop,我试图弄明白为什么在运行此代码时,每次迭代while循环都会打印两行代码: public void run() { long currentTime = System.nanoTime(); long targetFPS = 1000; long delta; while(GameConstants.running) { delta = System.nanoTime() - currentTime; if(delta/100000

我试图弄明白为什么在运行此代码时,每次迭代while循环都会打印两行代码:

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();
        }
    }
}
我试图将代码调整为只调用一次
System.out.println()
进行调试,但它仍在打印两次。我似乎不明白为什么会发生这种情况,因为在这个修改过的版本中,调用了
System.out.println(delta)
,然后将print设置为true,所以不应该再次调用
System.out.println(delta)

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 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();
}
}
public类游戏扩展画布实现可运行的keystener{
私有线程;
公共同步的void start(){
if(GameConstants.running)返回;
GameConstants.running=true;
gameThread=新线程(此线程);
gamesthread.start();
}
公共同步无效停止(){
如果(!gamestants.running)返回;
gamestants.running=false;
试一试{
gamesthread.join();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
公开募捐{
长currentTime=System.nanoTime();
长目标FPS=1000;
长三角洲;
布尔值=假;
while(GameConstants.running){
delta=System.nanoTime()-currentTime;
如果(增量/100000000>=1&&!打印){
系统输出打印项数(增量);
currentTime=System.nanoTime();
打印=真实;
}
}
}
公共无效更新(){
if(GameConstants.gameState==1&&!GameConstants.trialTypeDetermined){
随机r=新随机();
双prob=r.nextDouble();
if(prob=taskTime){
GameConstants.taskComplete=true;
GameContents.startTime=System.currentTimeMillis();
nextGameState();
GameConstants.keyPressed=false;
}
}
私有void nextGameState(){
if(gamesconstants.gameState==2&gamesconstants.skipBad){
gamestants.gameState=gamestants.gameState+2;
}else if(gamestants.gameState!=5){
gamestants.gameState++;
}否则{
gamestants.gameState=1;
}
gamestants.gameStateRegistered=false;
}
私有void重置参数(){
}
私有void checkHit(){
}
按下公共无效键(按键事件e){
int keyCode=e.getKeyCode();
if(keyCode==KeyEvent.VK_SPACE&&!GameConstants.keyPressed){
gamesconstants.keyPressed=true;
如果(!gamestants.reach){
GameConstants.reach=true;
GameContents.RT=System.currentTimeMillis();
}
}
}
公共无效密钥已释放(密钥事件e){
}
public void keyTyped(KeyEvent e){
}
公共静态void main(字符串[]args){
游戏=新游戏();
game.setPreferredSize(新维度(GameConstants.WIDTH*GameConstants.SCALE,GameConstants.HEIGHT*GameConstants.SCALE));
game.setMaximumSize(新维度(GameConstants.WIDTH*GameConstants.SCALE,GameConstants.HEIGHT*GameConstants.SCALE));
game.setMinimumSize(新维度(GameConstants.WIDTH*GameConstants.SCALE,GameConstants.HEIGHT*GameConstants.SCALE));
JFrame=新JFrame(“游戏”);
frame.setSize(GameConstants.WIDTH*GameConstants.SCALE,GameConstants.HEIGHT*GameConstants.SCALE);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setresizeable(false);
frame.add(游戏);
frame.setVisible(true);
game.start();
game.run();
}
}

如果已在同一对象上启动多个线程,则应使用同步块运行线程安全代码

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();
    }
}
}
更新源代码后

是啊!在这里,您正在调用run()方法并启动这两个

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

删除显式调用run方法,您将获得所需的结果:)

您的引导程序代码有缺陷您正在调用
start
run
有效地运行代码两次。删除对
run

的调用
run()
是如何调用的?有多个线程吗?为什么使用
&
而不是
&
?它应该不会引起任何问题,但很有趣。为什么说它在while()循环的每次迭代中打印两次?你在哪里计算/跟踪迭代次数?一旦我知道如何在注释中添加代码,我就会回答,因为我是新用户,所以我无法在答案中添加代码。问题是。没有答案。为什么这个问题仍然悬而未决?下面的两个答案都回答正确,你应该关闭它。啊,好的,这似乎解决了问题。我想我也必须叫run,因为我没有在别处叫它。非常感谢你!您的
start
方法创建一个
线程
,并启动它。该线程已经将调用
run
方法。