スレッドが長時間実行されないように保護する「WatchDog」を Java で作成する必要があります。オブジェクトの初期化では問題ありません。run() メソッドでリフレクションを使用して WatchDog とコンストラクターを呼び出すクラスを作成しました。
スレッドは簡単に停止できますが、オブジェクトの通常のメソッドを保護するにはどうすればよいですか? たとえば、オブジェクトのメソッドを呼び出し、このメソッドが無限ループを実行する場合、どうすればよいでしょうか?
ありがとう
まず、スレッドを停止するのは簡単ではないことを指摘しておく必要があります。実際、一般的なケースでは、スレッドを安全に停止することはできません。
Thread.interrupt()
停止したいスレッドを呼び出すことはできますが、実際に停止することは言うまでもなく、スレッドが割り込みに気付くという保証はありません。
非推奨のThread.stop()
メソッドを呼び出すことはできますが、このメソッドは安全ではありません。不幸な瞬間にそれを呼び出すと、データ構造を半分更新された状態のままにしたり、到着しないシグナルで他のスレッドを(永遠に)待機させたりすることができます。
メソッド実行のウォッチドッグを実装する方法は次のとおりです。
まず、メソッドを変更して、ウォッチドッグサービスに2つの呼び出しを追加します。例えば
public void someMethod(...) {
Watchdog.startMethod(maxTime);
// do stuff
Watchdog.endMethod();
}
次に、有効期限に順序付けられた優先キューを使用してウォッチドッグを実装します。
startMethod(maxTime)
、有効期限が。のエントリをキューに追加しますnow + maxTime
。エントリには、現在のスレッドへの参照が含まれます(メソッドが呼び出されたとき)。endMethod()
、現在のスレッドの()キューエントリを探し、見つかった場合はそれを削除します。endMethod
データ構造と、呼び出しがスキップされる場合に対処するために、いくつかの考慮が必要になります。(実際、メソッド呼び出しは例外によって終了する可能性があるため、endMethod()
呼び出しは実際にはブロック内で実行する必要がありfinally
ます。)
startMethod
andendMethod
呼び出しは、注釈プロセッサなどによって挿入される可能性がある(そしておそらく挿入されるべきである)ことに注意してください。
複雑さ、およびスレッドを(安全に)停止することを保証できないという事実を考えると、メソッドウォッチドッグを含まないソリューションを考えます。
オブジェクトの通常のメソッドは、いくつかのスレッドで実行されています。それは、AWT イベント ディスパッチャまたはそれが呼ばれるものである可能性があります。または、たとえば、コンソール アプリケーションのメイン スレッドである場合もあります。
これらは、new Thread() で呼び出されるスレッドと同じです。
ウォッチドッグは、VM 内のすべてのスレッドを調べて、使用率がしきい値以上のスレッドを探す必要があると思います。
これまでにどんなコードを持っていますか?
リッチ
jcabi-aspects の@Timeable
アノテーションを使用してみてください:
public class Resource {
@Timeable(limit = 5, unit = TimeUnit.SECONDS)
public String load(URL url) {
return url.openConnection().getContent();
}
}
メソッドはタイムアウトで中断されます。