我正在编写一个程序,其中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);
}
...
答案 0 :(得分:1)
您的关机线程永远不会中断主线程。它是一个与主线程分开的线程,所以当你调用
时 interrupt()
在它的主体中你要求这个线程中断自己。您需要将主线程添加到要终止的线程列表中。
将您的代码更改为:
List<Thread> killList = new ArrayList<Thread>();
....
for (int i = 0; i < 4; i++) {
Slave slaveThread = new Slave();
slaveMonitor.add(slaveThread);
}
killList.addAll(slaveMonitor);
killList.add(this);
并使用killList
终止线程。
答案 1 :(得分:0)
1)创建一个程序,它使用两种类型的线程:从属(传感器)和主机。
从属线程收集测量值并将它们转发到主线程
为简单起见,从站测量当前时间(System.currentTimeMillis())。只有主线程将值输出到控制台。度量存储在共享变量中。应从控制台读取从站数量。