我编写了一个 Java ME 益智游戏。我是这样编写代码的:有一个线程在应用程序启动时启动,一旦游戏开始,就会有第二个线程在无限循环中运行——主游戏循环。第二个线程一度看起来像这样:
public void run() {
init();
while (shouldIRun) {
updateGameState();
checkUserInput();
updateGameScreen(getGraphics());
this.flushGraphics();
}
}
可爱。这个线程一直运行,一直运行,直到我想杀死它,当我将 boolean 值 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();
}
}
关于java - 优雅地中断java线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9136837/