[英]Interrupting a java thread gracefully
我写了一个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
变量也为true。 我现在确定第二个线程已经暂停,并且我确切地知道了第二个线程已暂停的位置,“暂停”实际上是指“暂时卡在无限循环中”。 现在,我可以随意处理一些基本变量,重新启动级别,并大致进行分类,然后最后将shouldIWait
设置为false,然后再次进行操作。
我的问题是:对我来说,这很好,但是有点k头。 是否有某种完全标准的方式来做可能是常见的事情- 在给定的位置暂停线程,然后在我准备好后重新启动它,这比我正在做的要好? 我特别怀疑“将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();
}
}
也许杀死线程并以新级别开始新线程会更简单。
如果有一些信息需要从一个级别转移到另一个级别,则可以重构代码,以便首先收集一些常规信息,然后为每个级别启动一个线程。 (通过启动线程,我的意思是使用线程池。)
我不认为您当前正在忙着等待正在做什么,这不是邪恶的。 正如本·弗林(Ben Flynn)在评论中提到的那样,您可以通过遍历Thread.sleep(50)使其半忙。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.