Reputation: 247
I'm calling interrupt on day 370, and then calling it again during the catch block during the run method of the other classes. I also have a while condition that loops while thread is not interrupted, but for some reason, it's not working, and I have no idea why. I know I can use variable flag instead, but I want to try making interrupt() works. I've look at multiple sites already, but none seems to work for me. Please help.
public class Elf implements Runnable {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// wait a day
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
public class Main {
public static void main(String args[]) {
Scenario scenario = new Scenario();
// create the participants
// Santa
scenario.setSanta( new Santa(scenario) );
Thread th = new Thread(scenario.getSanta());
th.start();
// The elves: in this case: 10
for (int i = 0; i != 10; i++) {
Elf elf = new Elf(i + 1, scenario);
scenario.getElves().add(elf);
th = new Thread(elf);
th.start();
}
// The reindeer: in this case: 9
for (int i = 0; i != 9; i++) {
Reindeer reindeer = new Reindeer(i + 1, scenario);
scenario.getReindeers().add(reindeer);
th = new Thread(reindeer);
th.start();
}
// now, start the passing of time
for (int day = 1; day < 500; day++) {
// wait a day
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// turn on December
if (day > (365 - 31)) {
scenario.setDecember(true);
}
// interrupt flag is set here
if (day == 370) {
th.interrupt();
}
// print out the state:
System.out.println("*********** Day " + day
+ " *************************");
scenario.getSanta().report();
for (Elf elf : scenario.getElves()) {
elf.report();
}
for (Reindeer reindeer : scenario.getReindeers()) {
reindeer.report();
}
}
}
}
I've only included the Elf class here, but the other classes are of the same structure with almost the same code in it. Right now the program finishes with the red square (terminate button) still lit, and I read that that is an indication that there are still threads running. I'm not sure why it's not stopping.
Upvotes: 1
Views: 1639
Reputation: 34608
A variable declared as Thread th
is a reference to an object of type Thread
. It's only a reference to one object. This is true, by the way, for all types, not just thread.
Whenever you put a new value into a variable, it no longer refers to the old value[1].
Thus th.interrupt()
in your code will just interrupt the last thread that you assigned to it - the most recent reindeer thread.
If you want to interrupt all the threads, you'll need to keep a reference to all the threads.
A simple way to do this would be to use a list of Thread
:
List<Thread> allThreadsToInterrupt = new ArrayList<>();
When you create a thread, you do
th = new Thread(...);
allThreadsToInterrupt.add(th);
And then at the end you can do:
for ( Thread th: allThreadsToInterrupt ) {
th.interrupt();
}
ThreadGroup
But in fact, Java has an existing class that helps you with this - the ThreadGroup
class. You can do something like:
ThreadGroup elfThreads = new ThreadGroup("Elf Threads");
ThreadGroup reindeerThreads = new ThreadGroup( "Reindeer Threads" );
Now, whenever you create a thread, you should create it with a thread group:
Instead of:
th = new Thread(elf);
Use:
th = new Thread(elfThreads,elf);
Then at the end, to interrupt all the elves, you can run:
elfThreads.interrupt();
This would automatically call interrupt()
on all threads that belong to the group.
Of course, you can just create one big group, but I demonstrated separating the elves and the reindeer, in case you will need them to be interrupted separately.
[1] In most cases replacing an old reference, which was the only reference to an object, with a new reference will cause the old object to be eligible for garbage collection, but threads are a little different, because if they have been started, there is a second reference to them from the current thread group (because that's the default when you don't give a thread group when you create a thread), which means that they will not be garbage-collected and they will run properly until they complete.
Upvotes: 3