我目前正在研究一个java轰炸机人游戏,游戏运行正常,但我确实有一个并发修改异常,反复抛出。
在我的游戏中,我有两个玩家,每个玩家都有自己的线程,使用计时器以60fps的速度运行(thread.run()
)。在每个玩家运行方法结束时,我尝试重新运行重新运行线程以及线程运行。
方法1:
public void loop() {
if (!gameover) {
player1_thread.run(); //run player 1 thread
player2_thread.run(); //run player 2 thread
gui.repaint() //repaint panel
}
}
方法2:
public class Player extends Character { //Character implements Runnable
...
@Override
public void run() {
play();
...
game.render();
}
}
这两种方法都会按预期抛出并发修改,所以如何避免错误,只需执行以下操作:
player1.run(); //call the run method of each player class
player2.run();
为玩家1提供了优势。
修改
方法4:
import java.util.Timer
public class Player extends Character { //Character implements Runnable
private Timer gameTimer
@Ovveride
public void run() {
gameTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
play();
...
game.render();
}
}, 0, 1000/60);
}
}
public class Game extends AbstractGame {
private void init() {
...
Thread player1_Thread = new Thread(player1);
Thread player2_Thread = new Thread(player2);
gui = new GameGraphics(this); //subclass of JPanel
player1_thread.start();
player2_thread.start();
}
/* this method is called at a constant 60fps(like the player timer) in the main game timer in my abstract game class */
public void gameLoop(){
if(!gameover){
render();
...
}
}
}
这也会引发异常
答案 0 :(得分:0)
错误:调用run()将使用主线程执行指令。
正确:调用player1.start()来启动一个新线程,以便在新启动的线程中执行run(){...}。
答案 1 :(得分:0)
如果Player
是Thread
的子类,则可以使用.start()
启动它,但不要在循环中启动线程。你只需要启动一个线程,之后它将一直运行直到该类中的run方法完成,很可能你想用循环编写一个run方法,所以它一直运行到你停止它为止。如果你想只用一个线程来运行游戏,你可以实现Runnable
,并做你现在做的事情,在一个循环中调用run()
。那时只有一个主线程。
通过调用线程对象上的run,你没有启动一个线程,它只是在那个对象中调用run方法。
我认为最好的办法是,只需一个线程使用模型中的数据更新绘图。从播放器线程更改此模型中的数据。