在下面的示例中,我有一个主程序,可以创建6个任务和6个线程(每个任务1个)。如您所见,代码非常简单。我创建并启动了6个线程然后我想通过共享变量/ flag shutdownIssued
来停止所有线程。
但是,我看到主程序和线程没有终止(它们继续运行,我必须强行终止它们)。但是如果我先注释掉Thread.sleep(1000)
(即,在所有线程上调用shutdown()
之前),该程序将按预期工作。
1:为什么在当前(主)线程上调用Thread.sleep()
并不会导致线程停止(这意味着线程内的共享变量 shutdownIssued
不是真正通过主线程调用shutdown()来更新。
2:当我第一次发表评论Thread.sleep(1000)
时,为什么这会按预期工作?
示例代码:
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;
}
}
}