Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
优雅地中断java线程_Java_Multithreading_Java Me_Midp_Lcdui - Fatal编程技术网

优雅地中断java线程

优雅地中断java线程,java,multithreading,java-me,midp,lcdui,Java,Multithreading,Java Me,Midp,Lcdui,我写了一个javame益智游戏。我这样写代码:有一个线程在应用程序启动时启动,并且,一旦游戏开始,还有第二个线程在无限循环中运行-主游戏循环。第二条线在某一点上看起来像这样: public void run() { init(); while (shouldIRun) { updateGameState(); checkUserInput(); updateGameScreen(getGraphics());

我写了一个javame益智游戏。我这样写代码:有一个线程在应用程序启动时启动,并且,一旦游戏开始,还有第二个线程在无限循环中运行-主游戏循环。第二条线在某一点上看起来像这样:

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();
    }
}
我的想法如下。如果我现在想暂停第二个线程,从基本线程开始,我只需将shouldWait变量设置为true,然后循环直到我注意到iAmWaiting变量也是true。我现在可以肯定地知道第二个线程已经暂停了,并且我精确地知道它在哪里暂停了,我所说的暂停实际上是指它暂时被困在一个无限循环中。我现在可以在一些基本变量上游手好闲,重新启动关卡,然后把事情整理好,最后设置为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();
    }
}

也许更简单的方法是终止线程,并以新的级别启动一个新的线程

如果有一些信息需要从一个级别传递到下一个级别,那么您可以重构代码,首先收集一些一般信息,然后为每个级别启动一个线程。通过启动线程,我指的是使用线程池


我不认为你现在忙着等待是邪恶的。正如Ben Flynn在评论中提到的,通过在Thread.sleep50上循环,您可以让它处于半忙状态等待。

您至少可以在whileshouldwaiti-see中引入一个短线程睡眠-强制第二个线程睡眠,从而促使主线程重新运行?好的-完成:-这仍然是一个混乱的虽然?我希望有人会说,哦,使用t.pauseatthispoint untilisayso什么的……是的,这就是为什么我没有给出答案的原因我猜有人会和我一起讨论线程等待,但我认为我所建议的是一种自旋锁,有一些方法可以使用屈服和中断,这也可能是有效的。我不认为这是非常笨拙的,但我可能错了。我希望shouldIWait是易变的。以前版本的程序用来做这个,但需要传递各种参数,我有点担心某些参考循环可能会发生,然后我意识到我可以按照上面的建议去做,然后就这样做了。我会接受这一点,因为它教会了我一些东西。我是否会抽出时间来实施它是另一回事:-但我可能会,在一天结束时。