3

マルチスレッドプログラムがあり、1つのスレッドで複数のスレッドを監視しています。機能は次のように設計されています。

メインプログラムが開始を行い、ウォッチャースレッドを開始します。voidMain()で、次の行があります。

Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownThread(), "Exit Listener"));

ウォッチャースレッドを開始しない場合、プログラムの終了時にShutdownThreadが呼び出されますが、デッドループのあるウォッチャースレッドを開始すると、ShutdownThreadが呼び出されません(そのスレッドでメッセージを出力します) 。それは非常に奇妙です。説明はありますか?

ウォッチャースレッドは次のようなものです。

public void run(){
   boolean running=false;
   thread a=new thread(...); //Do the same thing for b, c, d...
   while(true){
   if (a.isActive()){
     if (running)
        thread a= new thread(...);
     a.start();
     running=true;
   }
   Thread.sleep(1000); //try catch block...
}

私が欲しいのは、終了シグナルを受け取ると、shutdownThreadが実行され、フラグを設定してすべてのスレッドに割り込み、スレッドが割り込むのを待つか、残りのスレッドを強制終了できるようにタイムアウトする、正常なシャットダウンです。すべてのスレッドが割り込みをキャッチし、フラグが設定されているかどうかを確認できます。設定されている場合は、shutdownThreadを中断して、それ自体を終了します。代わりに、私が見ているのは、すべてのスレッドがそれ自体で終了していて、クリーンアップをまったく行っていないことです。

信号を使ってみませんか?そのための優れたクロスプラットフォームコードはありますか?

その場合、setUncaughtExceptionHandlerも機能しません。テストを行ったところ、ハンドラーがまったく呼び出されていないことがわかりました。どうしてか分かりません。ハンドラーのコードは次のとおりです。

    public static class ErrHandler implements Thread.UncaughtExceptionHandler{
    public final void uncaughtException(Thread t, Throwable e) {
            Error(t + "died, threw exception: " + e);
        }
    }//this is in public class globals

私はそれを使用してフックします

producer.setUncaughtExceptionHandler(Globals.errhandler);

私のコードにあり、代わりに元のe.printStack()のみが表示されます。親スレッドでも、それ自体でも、オーバーライドできないようです。これはとてもイライラします。エントリをキューに入れて、他の場所で読み取ることを考えています。少なくともそれはうまくいくかもしれません。

ああ、全体の目的は、実行時の例外が原因でスレッドのいずれかが停止した場合に、ウォッチャースレッドが例外が十分に致命的であるかどうかを確認し、そのスレッドを再起動するか、完全に終了するかを決定することです。同時に、ユーザーがプログラムを終了したときに、プログラムを正常に終了するようにします(割り込みがセーバースレッドに送信され、結果がダンプされてから、割り込みを返し、終了する準備ができていることを通知します)。

4

1 に答える 1

0

それがあなたを助けるならDunno、しかし私達は同じ振る舞いに遭遇しました。すべての例外が登録済みのExceptionHandlerに正しくルーティングされるわけではありません。

並行フレームワークの単体テストは存在するのだろうか。これを検出する必要があったからです。

ScheduledExecutorServiceインスタンスをデリゲートとして使用してScheduledExecutorServiceを自分で実装し、各メソッドのパラメーターRunnable/CallableをRunnable/Callable実装にカプセル化して動作を修正しました。

于 2010-02-26T11:30:22.030 に答える