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);
}
...