1

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

2 に答える 2

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てスレッドを終了します。

于 2012-11-22T16:02:52.443 に答える
0

1)スレーブ(センサー)とマスターの2種類のスレッドを利用したプログラムを作成します。

スレーブ スレッドは測定値を収集し、マスター スレッドに転送します。

簡単にするために、スレーブは現在の時間を測定します (System.currentTimeMillis())。マスター スレッドだけが値をコンソールに出力します。メジャーは共有変数に格納されます。スレーブの数はコンソールから読み取る必要があります。

于 2014-11-18T14:56:25.287 に答える