1

現在、JMX を使用して、Java クラス内で実行される大規模な移行プロセスを管理および監視しています。

必要なときにプロセスを中止して強制終了できるようにしたいと考えています。たとえば、顧客/時間が必要な場合や、1 回の移行でデッド ループが発生した場合などです。

ここでは、boolean フラグを設定してスレッドを強制終了するための適切な方法として abort を呼び出します。すべてのループが最初にフラグをチェックしてから、続行するかどうかを決定します。これは問題なく実装されています。

ただし、スレッドを強制終了するのに問題があります。私の同僚は、 finalize() メソッドをオーバーライドして、その中で強制終了するように提案してくれました。ただし、私がオンラインで見つけたのは、このメソッドはオブジェクトを破棄できず、GC ではなくユーザーによって呼び出されることをお勧めします。

オブジェクトが破壊されている限り、それ以上のプロセスは起こらないという理論は正しいと思います。これがJAVAで実装できるかどうかはわかりません。

また、他に何かヒントがあれば教えていただきたいです。

よろしくお願いいたします。

PS: JMX に関連するということは、それが実際に JMX と関係があるという意味ではありません。ただ、この強制終了コマンドが JMX コンソール クライアントから送信されることを望みます。

4

2 に答える 2

2

何を言っているのかわかりにくいですが、参考にはならないと思いfinalizeます。

  • ライブ スレッド (つまり、開始されていてまだ終了していないスレッド) は、定義上到達可能であるため、ガベージ コレクションの対象にはなりません。したがって、finalize メソッドを追加しても影響はありません。

  • あなたが話しているオブジェクトがスレッドではない場合、ファイナライズを追加してもおそらく役に立たないでしょう:

    • スレッドの実行可能なもの (または何でも) がオブジェクトへの参照を持っている場合、ガベージ コレクションが停止します。
    • そうでない場合、オブジェクトが到達不能になるとfinalize、GC がオブジェクトを収集することを決定するまでメソッドは実行されません...そして、それは決して起こらない可能性があります。
    • メソッドが呼び出されたとしてもfinalize、何ができるでしょうか? あなたはすでにスレッドにシャットダウンするように指示しました...そして何も起こりませんでした.

ここでの本当の問題は、スレッドが「正常なシャットダウン」フラグに応答していないことです。

  • カスタムフラグではなくThread.interrupt()andを使用して、これを修正しようとします。これには、割り込みが特定の I/O 操作などのThread.isInterrupted()ブロックも解除するという利点があります。Thread.sleep Object.wait

  • スレッドがソケットまたはパイプを介して外部サービスと通信しようとしてブロックされている場合は、ソケットやストリームを閉じることでブロックを解除できます。もちろん、これは、シャットダウン コードが Socket または Stream オブジェクトへの参照を取得できることを前提としています。

  • これらのアプローチが失敗した場合は、... を呼び出してアプリケーション全体のプラグを抜くことを検討System.exit()します。それが合理的なことであれば。

  • あなたが完全に絶望的である(そして少し狂っている)場合は、非推奨のThread.abort()方法を使用することを検討できます. しかし、そうすると、アプリケーション全体が壊れて応答しない状態になる可能性が明確にあります。したがって、このアプローチはお勧めしません。

考慮すべき他の可能性は次のとおりです。

  • スレッドが実際に応答して終了したが、シャットダウン コードが気付かなかった、
  • スレッドをシャットダウンしようとする前にスレッドが終了し、シャットダウン コードが気付かなかったこと、
  • スレッドがデッドロックされていること、または
  • ランナブルに長時間実行される (ただし無限ではない) ループがあることを修正して、「you die now」フラグをより頻繁にチェックするように変更する必要があります。

これらのいくつかは、デバッガーを接続してスレッド ダンプを取得することで診断できます。


電話するのは悪い考えだという趣旨のアドバイスを見たとあなたは言ったと思いますSystem.gc()。これは良いアドバイスです。

于 2011-03-30T06:56:10.570 に答える
0

finallyメソッドが何らかの状態で終了したときに実行したい特定のタスクを実行する必要があります。これについて人々が与える最も好ましい例は、データベース接続のcosingです。

はい、ガベージ コレクションを JVM に残すことをお勧めします。

JVM は、オブジェクトの破棄を処理します。

于 2011-03-30T06:53:29.433 に答える