3

addShutdownHook()を使用してCtrl + Cを処理するSwingアプリケーションがあり、通常の状況でJLabelテキストを変更する関数を呼び出すシャットダウンタスクの1つまで正常に動作し、その時点でハングします。

問題は、Swing EDTが終了したか、何かを待っていることだと思います。

EDTが終了したか「完了」したかを判断する方法(Swingメソッドの呼び出しを回避できるようにするため)、またはCtrl-Cでの通常のウィンドウを閉じる動作を防ぐ方法はありますか?


明確にするために:

というクラスのメソッドがありstop()ます。通常の状況では、これは(その補足とともにstart())呼び出される可能性があり、発生した視覚的なフィードバックのために、JLabelが更新される原因となる一連の事柄をトリガーしますstop()

シャットダウンフックが実行されたら、stop()いくつかのリソースを正常にシャットダウンするために呼び出す必要があります。

私が求めているのは、Swing EDTが存在しないことをどのように検出できるかということです。そのためstop()、Swingの欠如を検出し、Swing関数の呼び出しを回避するように書き直すことができます。

4

3 に答える 3

5

次のハックは、JVMがフラグを渡さずにシャットダウン中であるかどうかを判断するのに役立ちます。

private static final Thread DUMMY_HOOK = new Thread();

public static boolean isShuttingDown()
{
    try {
        Runtime.getRuntime().addShutdownHook(DUMMY_HOOK);
        Runtime.getRuntime().removeShutdownHook(DUMMY_HOOK);
    } catch ( IllegalStateException e ) {
        return true;
    }

    return false;
}

ただし、同時実行の問題の可能性を忘れないでください。

于 2011-11-10T15:14:46.217 に答える
2

シャットダウンフックは、アプリケーションのシャットダウンが要求されているため、他のサービスが既知の状態(UIイベント処理スレッドなど)であることを期待してはなりません。フックの制御範囲内に100%ないものを更新しようとするシャットダウンフックを作成すると、これやその他の動作が発生し、トラブルシューティングが困難になる可能性があります。

このaddShutdownHookメソッドはこのケースに具体的に言及しており、これらのタイプのアクションを試してはいけないことを警告しています。そうすると、観察したロックアップなどの予期しない結果が簡単に発生する可能性があるためです。

ドキュメントから:

シャットダウンフックは、仮想マシンのライフサイクルの微妙なタイミングで実行されるため、防御的にコーディングする必要があります。特に、スレッドセーフであり、可能な限りデッドロックを回避するように作成する必要があります。また、独自のシャットダウンフックを登録している可能性があるため、シャットダウンの過程にある可能性のあるサービスに盲目的に依存するべきではありません。

この場合、Swingはユーザーが制御できないマルチスレッドUIシステムであるため、プログラムのライフサイクルのシャットダウン段階でUIを変更しようとしないことをお勧めします。これを行うと、スレッドがシャットダウンするようにスケジュールされる方法に応じて、実行ごとに、またはマシンごとに異なる可能性のある、奇妙で予測不可能な、場合によっては再現不可能な状況が発生します。別のスレッドがその作業を停止する方法とタイミングは、線形で予測可能な方法で発生するようには設計されていません。そのため、特定の時間に特定の状態にある別のスレッドに依存するマルチスレッドプログラムで作成するコードは、(それらのスレッドが状態について互いに明確に通信している場合を除き)、これらの種類のコードにアクセスできます。問題。

私のフォローアップの質問は、「シャットダウンプロセス中にJLabelを変更する必要があるのはなぜですか?」というものだと思います。シャットダウン前に何かの状態を変更したい場合は、キーボード入力を通常のイベントとしてキャッチし(アプリケーションが閉じないようにする)、JLabelテキストを変更してから、のシャットダウンを開始することをお勧めします。 System.runFinalization()および/またはSystem.ext(int)の呼び出しを介してアプリケーションを自分で

于 2011-07-25T14:15:07.843 に答える
0

シャットダウンフックの先頭にフラグを設定し、これを(事前に設定されたオブジェクトを介して)stop()メソッドを使用してオブジェクトに伝達し、このフラグをテストしてSwingメソッドを呼び出すかどうかを決定できるようにしました。 。

シャットダウンフラグが設定されていない場合、Swingメソッドが呼び出されます。そうでなければ、彼らはしません。

于 2011-07-25T16:37:23.950 に答える