如果在while true循环中有System.out.println(),则线程只能正确运行

时间:2011-08-21 19:28:15

标签: java multithreading

基本上,我正在制作一款更新球员位置的游戏,它使用这个帖子:

@Override
public void run() {
    while(true) {
        System.out.println();
        updatePos(x, y);
    }

}

哪个工作正常,但如果我删除System.out.println(),它就会停止运行。我不知道为什么会这样,全班如下:

public class Player extends Block implements KeyListener, Runnable {

int x;
int y;
int speed;

boolean upPressed; 
boolean downPressed;
boolean rightPressed;
boolean leftPressed;

static Sprite sprite = new Sprite("grass.png");

public Player(int x, int y, int speed) {
    super(x, y, sprite);
    this.x = x;
    this.y = y;
    this.speed = speed;
    Thread playerThread = new Thread(this, "Player Thread");
    playerThread.start();
}

@Override
public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_UP) {
        y -= speed;
    }

    if (e.getKeyCode() == KeyEvent.VK_DOWN)
        downPressed = true;

    if (e.getKeyCode() == KeyEvent.VK_RIGHT)
        rightPressed = true;

    if (e.getKeyCode() == KeyEvent.VK_LEFT)
        leftPressed = true;

}

@Override
public void keyReleased(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_UP)
        upPressed = false;

    if (e.getKeyCode() == KeyEvent.VK_DOWN)
        downPressed = false;

    if (e.getKeyCode() == KeyEvent.VK_RIGHT)
        rightPressed = false;

    if (e.getKeyCode() == KeyEvent.VK_LEFT)
        leftPressed = false;

}

@Override
public void keyTyped(KeyEvent e) {

}

@Override
public void run() {
    while(true) {
        System.out.println();
        updatePos(x, y);
    }

}}

最后注意事项:在布尔值upPress和downPressed中,我唯一关注的是:

if (e.getKeyCode() == KeyEvent.VK_UP) {
    y -= speed;
}

5 个答案:

答案 0 :(得分:7)

这样的循环
while(true) {
    updatePos(x, y);
}

会完全占用CPU。使用println开始表现更好的原因可能是因为I / O每次迭代产生几百个周期。

我建议您根据所需的帧速率添加一个小的睡眠方法:

while (true) {
    try {
        Thread.sleep(10); // for 100 FPS
    } catch (InterruptedException ignore) {
    }
    updatePos(x, y);
}

或更好的是,使用事件驱动的方法,例如java.util.Timer。 (这将是Java惯用语。)

答案 1 :(得分:1)

不知道是否会解决它,但看起来你给JVM带来了困难...... 尝试在每次updatePos(x,y)调用之前添加一个短暂的睡眠(这是实现游戏线程的正确方法)。

@Override
public void run() {
    while(true) {
    Try
    {
        Thread.sleep(50);
    }
    catch (Exception e){}

    updatePos(x, y);
    }

}}

答案 2 :(得分:1)

您没有将代码发布到updatePos。但至少,您需要制作该方法,以及keyPressed(以及使用x和/或ysynchronized的任何其他方法。

或者,您可以同时制作xy volatile,但xy可以更新锁定。

但是没有任何内存同步,一个线程的更改不能保证可以从另一个线程中观察到。

答案 3 :(得分:0)

还有另一个方法。您可以使用专用于执行计划任务的类java.util.Timer。如果您现在需要2个线程定期执行某种不同的操作,那么它非常有用。使用Timer,您只需使用一个线程就可以节省您的工作和计算机资源

答案 4 :(得分:0)

在某些情况下,Thread.yield()也可以做到。 例如,请参见https://www.javamex.com/tutorials/threads/yield.shtml。 但是,此链接的作者不建议使用yield