我正在编写一个程序,其中 Main 类初始化并启动一个主线程。这个主线程启动n
从线程。该程序应使用终止Ctrl+C
。主线程必须停止从线程并最终停止自己。我已经阅读了很多addShutdownHook
,这是我的简化实现:
package dictator;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Master m = new Master();
m.start();
}
}
class Master extends Thread {
List<Slave> slaveMonitor = new ArrayList<Slave>();
public Master() {
for (int i = 0; i < 4; i++) {
Slave slaveThread = new Slave();
slaveMonitor.add(slaveThread);
}
Thread shutDown = new Thread() {
@Override
public void run() {
try {
System.out.format("%nShutting down threads...%n");
for (Slave s : slaveMonitor) {
s.interrupt();
s.join();
}
interrupt()
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
};
Runtime.getRuntime().addShutdownHook(shutDown);
}
@Override
public void run() {
for (Slave s : slaveMonitor) {
s.start();
}
while (true) {
System.out.println(getName() + " - Master");
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println(getName() + " interrupted.");
break;
}
}
System.out.println(getName() + " exiting.");
}
}
class Slave extends Thread {
public Slave() {}
@Override
public void run() {
while (true) {
System.out.println(getName() + " - Slave");
try {
Thread.sleep(1500);
} catch (InterruptedException ex) {
System.out.println(getName() + " interrupted.");
break;
}
}
}
}
addShutdownHook
捕获信号并终止所有从属线程,但我没有看到主线程退出(行System.out.println(getName() + " interrupted.");
和在主线程的System.out.println(getName() + " exiting.");
运行主体中。
这是我的终端的输出:
Thread-1 - Slave
Thread-2 - Slave
Thread-3 - Slave
Thread-0 - Master
Thread-4 - Slave
Thread-0 - Master
^C
Shutting down threads...
Thread-1 interrupted.
Thread-2 interrupted.
Thread-3 interrupted.
Thread-4 interrupted.
我不应该看到以下行吗?我做错了什么?
Thread-0 interrupted.
Thread-0 exiting.
更改主线程
class Master extends Thread {
List<Slave> slaveMonitor = new ArrayList<>();
List<Thread> killList = new ArrayList<>();
public Master() {
for (int i = 0; i < 4; i++) {
Slave slaveThread = new Slave();
slaveMonitor.add(slaveThread);
}
killList.add(this);
Thread shutDown = new Thread() {
@Override
public void run() {
try {
killList.addAll(slaveMonitor);
Collections.reverse(killList);
System.out.format("%nShutting down threads...%n");
for (Thread t : killList) {
t.interrupt();
t.join();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
System.out.println("Interrupted shutdown process");
System.exit(1);
}
}
};
Runtime.getRuntime().addShutdownHook(shutDown);
}
...