In the example below, I have main program that creates 6 tasks and 6 threads (1 per task). As you can see, the code is really very simple. I create and start 6 threads and then I want to stop all the threads through a shared variable/flag shutdownIssued
.
However, I am seeing that the main program and threads don't ever terminate (they keep running and I have to forcefully terminate them). But the program works as expected if I comment out first Thread.sleep(1000)
(ie., before calling shutdown()
on all the threads).
1: Why calling Thread.sleep()
on current(main) thread doesn't cause threads to stop (which means that shared variable shutdownIssued
inside the threads is not really updated by a call to shutdown() by the main thread).
2: Why does this work as expected when I comment out first Thread.sleep(1000)
?
Example code:
package com.examples.threads;
import java.util.ArrayList;
import java.util.List;
public class ThreadExample {
public static void main(String[] args) {
//create 6 tasks and 6 threads to run them
int numTasks = 6;
List<Task> tasks = new ArrayList<Task>();
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < numTasks; i++) {
tasks.add(new Task());
Thread th = new Thread(tasks.get(i));
threads.add(th);
th.start();
}
//Wait for 2 seconds before issuing shutdown
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Now issue shutdown request to all the threads to stop execution of their assigned task
for (int i = 0; i < numTasks; i++) {
tasks.get(i).shutdown();
}
//Wait for 2 seconds after issuing shutdown
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Check if threads are still alive
for (int i = 0; i < numTasks; i++) {
System.out.println("Thread " + threads.get(i).getName() + " is alive = " + threads.get(i).isAlive());
}
System.out.println("finished shutdown of all the threads!!");
}
public static class Task implements Runnable {
private boolean shutdownIssued = false;
private String name;
public void shutdown() {
shutdownIssued = true;
System.out.println("Issued shutdown to " + name);
}
public String getName() {
return name;
}
public void run() {
this.name = Thread.currentThread().getName();
System.out.println("started thread " + name);
int cnt = 0;
while (!shutdownIssued) {
//System.out.println("inside thread " + Thread.currentThread().getName());
cnt++;
}
System.out.println("Finished thread " + name + ", count = " + cnt);
}
public boolean isShutdownIssues() {
return shutdownIssued;
}
}
}