Reputation: 3042
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 while
loop in each class, which runs as long as a boolean called running
equals to true
.
I then stop the program by calling a method called stop
. The stop
method only sets running
to false, so that the while loop exits.
EDIT Code:
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();
}
Upvotes: 4
Views: 17691
Reputation: 2662
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.
Read about setDaemon in documentation http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#setDaemon(boolean)
Upvotes: 0
Reputation: 3020
I believe you should rewrite your run() method:
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:
public void stop() {
thread.interrupt(); //use thread here, not game
}
Add a join() method:
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.
What is not clear to me yet, is how exactly you invoke stop().
Upvotes: 1
Reputation: 1854
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()
.
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:
// 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
}
Upvotes: 3