我写了一个
Java ME益智游戏.我编写了这样的代码:有一个线程在应用程序启动时启动,并且,一旦游戏开始,就会有第二个线程在无限循环中运行 – 主游戏循环.第二个线程看起来像这样,有一点:
public void run() {
init();
while (shouldIRun) {
updateGameState();
checkUserInput();
updateGameScreen(getGraphics());
this.flushGraphics();
}
}
可爱.这个线程只运行并运行,直到我想杀死它,当我只是将布尔值shouldIRun设置为false时,它就会优雅地退出.
但后来我意识到我想要更多.游戏是一个益智游戏,玩家可能会做出错误的动作然后卡住.发生这种情况时,他们可以启动表单并选择“重启级别”选项.然后设置一个标志restartLevel,当无限循环到达updateGameState()方法时,重新启动该级别.但这对我来说有点像赌博 – 我不想在并发问题的情况下开始更改主循环中使用的对象的变量,尽管我可能是偏执狂.在实践中,我意识到我想要做的非常明确:我只是想暂停无限循环线程,将变量更改为我想要的,然后重新启动.
我通过以下方式完成此操作:
public void run() {
init();
while (shouldIRun) {
if (shouldIWait) {
iAmWaiting=true;
while (shouldIWait) { };
iAmWaiting=false;
}
updateGameState();
checkUserInput();
updateGameScreen(getGraphics());
this.flushGraphics();
}
}
我在想的是以下内容.如果我现在想要“暂停”第二个线程,从“基础”线程,我只需将shouldIWait变量设置为true,然后循环直到我注意到iAmWaiting变量也为真.我现在肯定知道第二个线程已经暂停,我确切地知道它暂停的位置,“暂停”我实际上意味着“暂时停留在无限循环中”.我现在可以解决一些基本变量,重新启动关卡,并通常将事情排序,最后将shouldIWait设置为false,然后再关闭.
我的问题是这样的:对我而言,这样做很好,但有点像是一块垃圾.是否有一些完全标准的方法来做可能是常见的事情 – 在给定点暂停线程然后在我准备好时重新启动它,这比我正在做的更好?特别是我怀疑“将java放入无限循环”可能不是一件聪明的事情.
最佳答案 通常,这是您将使用Object.wait()和Object.notify().
有几种方法可以根据您的情况实现它,但这是一个简单的例子:
Object monitor = new Object();
volatile boolean done = false, wait = false;
/* Running on one thread: */
public void run() {
synchronized(monitor) {
while(!done) {
while(wait) {
monitor.wait();
}
gameLogicAndStuff();
}
}
}
/* Running on another thread: */
public void showResetForm() {
wait = true;
synchronized(monitor) {
actuallyShowResetForm();
wait = false;
monitor.notifyAll();
}
}