0

Java Daemon (Daemon と Runnable を実装するクラス) を作成しましたが、現在、次の問題に直面しています。

init() で、新しいスレッドを作成します。Thread thread = new Thread(this); start() で、新しいスレッドを開始します。thread.start(). 実行中、私はさまざまなことをたくさん行います....すると例外が発生します。(私の場合: NullPointerException.)。

ここで、run() で例外をキャッチし、stop() を呼び出します。そこで を呼び出しますthread.join()が、これは決して終了せず、InterruptedException はスローされません。どうすればこの問題を解決できますか?

run() では、while ループでいくつかのことを行います

private Thread thread;

public void init() {
    // if init is successful: this.thread = new Thread(this);
    // if init is not successful: call stop()
}

public void run() {
  try{
  // do something
  while (!this.stopping)
  {
      // do somthing
  }
  } catch (Exception e) {
      //do something and then call stop()
  }
}

public void stop() {
    this.stopping = true;
    thread.join(); // catch InterruptedException if it did not work
    // do some more things
}

ここで例外がスローされます。停止は揮発性であり、停止が呼び出されるとすぐに true に設定します。

ありがとうございました :-)


たくさんの答えが得られましたが、まだこの問題は解決していません。run() または init() メソッドで手動で stop() を呼び出すべきではないと誰もが言いました。私の問題は、init() または run() で例外が発生したときに、プログラムを本当に停止したいということです。プログラムがもう実行されないように、それを終了します。stop() を呼び出さずにこれを達成する方法がわかりません。run() が終了するまで待つだけではうまくいきません。また、例外の問題を処理する方法もまだわかりません。

4

3 に答える 3

2

通話stopは問題ありません。人々はあなたに電話しないように警告してThread.stop()いますが、あなたはそれをしていません。あなたjoinやっていることは、参加したいのとまったく同じスレッドで呼び出していることです - もちろん、デッドロックが発生します。あなたが持っている

catch (Exception e) {
  //do something and then call stop()
}

つまり、実際にメソッドから呼び出していることを意味します。それは間違っている。キャッチブロックに入らなかったため、例外なく機能しました。その catch ブロックに書き込む必要があるのは、while ループを中断することだけです。stoprunbreak;

余談ですが、 への参照はまったく必要ありません。これはThread混乱を招くだけです。メソッドが実行されているThreadインスタンスにアクセスする必要がある場合は、 を呼び出すだけです。runThread.currentThread()

于 2012-05-30T12:06:27.577 に答える
1

あなたの例はまだコードの一部にすぎないため、何が間違っているのかを正確に知ることは困難です。私が作成できる最も単純なマルチスレッド プログラムを添付します。メイン スレッドは 100 ミリ秒ごとに「main」を出力します。もう一方のスレッドは、停止するまで 100 ミリ秒ごとに「other」を出力します。メイン スレッドは、10 回の反復後に他のスレッドを停止します。このプログラムでは実行できないことを説明できますか? それができるまで変更できます。

public class Main {

    private Thread thread;
    private Other other;

    public static void main(String args[]) throws InterruptedException {
        Main main = new Main();
        main.run();
    }

    public void run() {
        other = new Other();
        thread = new Thread(other);
        thread.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("main");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                System.out.println("interrupted waiting for sleep in main");
            }
        }
        stop();
    }

    public void stop() {
        other.stopping = true;
        try {
            thread.join();
        } catch (InterruptedException e) {
            System.out.println("interrupted waiting for other to join main");
        }
    }

}

class Other implements Runnable {

    volatile boolean stopping;

    @Override
    public void run() {
        while (!stopping) {
            System.out.println("other");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                System.out.println("interrupted waiting for sleep in other");
            }
        }
    }

}
于 2012-06-01T01:33:13.900 に答える
1

stop を呼び出すべきではありません。実行から戻るか、実行から例外をスローするだけで、スレッドは自動的に停止します。Thread.join は、デーモン スレッドが完了するのを待ちたいスレッドから呼び出されることを意図しています。たとえば、メイン スレッドがシャットダウンのメッセージを受信した場合、メイン スレッドはデーモンに停止するように通知し (stop を呼び出すのではなく)、join を使用してデーモンが実際に停止するのを待ちます。ここにチュートリアルがあります。

于 2012-05-30T12:04:20.673 に答える