java Thread.join() 和 Thread.interrupt() 不会停止线程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27469761/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 11:50:49  来源:igfitidea点击:

Thread.join() and Thread.interrupt() doesn't stop the thread

javamultithreadingloops

提问by Daniel Kvist

I'm having some issues with stopping my threads.
I've tried calling both Thread.join()and Thread.interrupt(), alone and together, but I can't get it working.
I have a whileloop in each class, which runs as long as a boolean called runningequals to true.
I then stop the program by calling a method called stop. The stopmethod only sets runningto false, so that the while loop exits.

我在停止线程时遇到了一些问题。
我试过单独和一起调用Thread.join()and Thread.interrupt(),但我无法让它工作。
while在每个类中都有一个循环,只要名为runningequals to的布尔值就会运行true
然后我通过调用一个名为 的方法来停止程序stop。该stop方法仅设置running为 false,以便退出 while 循环。

EDITCode:

编辑代码:

public class Game implements Runnable {

    // The Thread
    private Thread thread;

    // The program's running state
    private boolean running = false;

    // Create the Thread and the rest of the application
    public void create() {
        // Create the Thread
        thread = new Thread(this, "Game");
        // Start the Thread
        thread.start();
        // Set the program's running state to true
        running = true;
    }

    public void run() {
        while(running) {
            // Render, update etc...
        }

        // When the while loop has exited
        // (when running is false (when the stop method has been called))
        try {
            // Join the thread
            thread.join();
            // Interrupt the thread
            thread.interrupt();
        } catch(InterruptedException e) {
            // Print the exception message
            e.printStackTrace();
        }
        // Exit the program
        System.exit(0);
    }

    // Stop the game
    public void stop() {
        // Set the program's running state to false
        running = false;
    }

    // The main method
    public static void main(String[] args) {
        // Create a new instance of Game and start it
        new Game().create();
    }

采纳答案by Gren

The thread blocks itself
A thread ends, when the run method is finished, but you call the join()method inside the run()method and this method waits until the thread is finished. So the run()method never ends and the thread will never die.
You have done correct, to implement a while, which tests a boolean you can set in a method to end the thread.
To end the thread and waiting on its end, call the join()method after calling the stop().
The System.exit(0)in the run method is not needed. If your thread ends and the join() method returns, the main method ends and so the program is finished.I know, your real program will be more complex, but you don't need System.exit().

线程阻塞自己
一个线程结束,当 run 方法完成时,但是您在join()方法内部调用该run()方法并且该方法等待直到线程完成。所以run()方法永远不会结束,线程永远不会死。
你做对了,实现了一段时间,它测试了一个布尔值,你可以在方法中设置来结束线程。
要结束线程并等待其结束,请join()在调用stop().
System.exit(0)run方法是没有必要的。如果您的线程结束并且 join() 方法返回,则 main 方法结束,因此程序完成。我知道,您的实际程序会更复杂,但您不需要System.exit().

public void run() {
    while(running) {
        // Render, update etc...
    }
}

// The main method
public static void main(String[] args) {
    // Create a new instance of Game and start it
    Game game = new Game().create();
    game.stop();
}

EDIT 1:

编辑 1:

// Stop the game
public void stop() {
    // Set the program's running state to false
    running = false;
    game.interrupt();//Cause blocking methods like Thread.sleep() to end with an Interrupted exception
    game.join();//Wait until the thread is completed
}

回答by parakmiakos

I believe you should rewrite your run() method:

我相信你应该重写你的 run() 方法:

public void run() {
    while(true) {
        // Render, update etc...

        // at the end, or after some steps, according to Java doc for Thread
        if (Thread.interrupted())  
           throw new InterruptedException();
    }
}

And your stop() method, simply interrupting the thread should do it:

而您的 stop() 方法,只需中断线程即可:

public void stop() {
    thread.interrupt();  //use thread here, not game
}    

Add a join() method:

添加一个 join() 方法:

public void join() throws InterruptedException {
    thread.join(); 
}    

So in your main, you join your thread

所以在你的主要,你加入你的线程

public static void main(String[] args) {
    // Create a new instance of Game and start it
    Game game = new Game();
    game.create();
    try {
        game.join();
    } catch (InterruptedException e) {
        //The interrupt should occur from another thread

        //Somebody called stop()
        //do your clean up
        System.exit(0);
    }           
}   

This is the related JavaDoc.

这是相关的JavaDoc

What is not clear to me yet, is how exactly you invoke stop().

我还不清楚的是,您究竟如何调用 stop()。

回答by Vitaly

As far as I understand you need to stop all your threads when your game exits from main. You can setDaemon(true) to all your threads and they will be closed automatically.

据我了解,当您的游戏从 main 退出时,您需要停止所有线程。您可以将Daemon(true) 设置为所有线程,它们将自动关闭。

Read about setDaemon in documentation http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#setDaemon(boolean)

在文档http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#setDaemon(boolean) 中阅读有关 setDaemon 的信息