2011-08-03 5 views
0

タスクが中断されたときに、リソースの解放を強制する必要があります。そのために、this solutionを実装しました。しかしこれで、私がshutdown()と呼ぶとき、ScheduledThreadPoolExecutor.getQueue()のすべてのタスクは正しく強制されますが、私の仕事の中にはリソースが残っています。私はその動作を非常にうまく確認しました。これを理解しました。タスクが実行中のとき、彼はScheduledThreadPoolExecutorキューに存在しません(明らかに分かります)。問題は、すべてのジョブ(キュー内または実行中)のリソースの解放を強制する必要があることです。ScheduledThreadPoolExecutorで実行中のジョブを取得するにはどうすればよいですか?

したがって、実行中のジョブを取得するにはどうすればよいですか。あなたは良いアイデアを持っていますか?

答えて

2

ジョブを送信するときに作成するすべての未来のリストを管理することができます。 このリストを使用してすべての先物をキャンセルします。

+0

これは現在実際に実装されていますが、このソリューションでは、スケジュールされたすべてのジョブ(実行されたジョブも含む)への参照が保持されます。処理する必要があり、スケジューラーが処理するまでメモリに格納されますtdown。これはガベージコレクションに問題を引き起こすでしょうか? – ggarciao

+0

最後のN先物は残しておく必要があります。あなたはある時点の後に先物をキャンセル/破棄することができます。システムがあまりにも遅れてしまった場合は、解決するのがより複雑な問題があります。 –

1

あなたは(あなたが割り込みフラグを使用して、各タスクの「中断ポリシー」を実装する必要がありますThread.interruptを使用して)タスクを実行している現在、キャンセルしようとします

executor.shutdownNow() 

を呼び出すためにしたくありません。 javadocのから

実行中のアクティブなタスクすべての停止を

試み、待機中のタスクの処理を停止し、実行を待機していたタスクのリストを返します。

実行中のタスクの処理を最善の努力で止めようとしても保証はありません。たとえば、典型的な実装ではThread.interruptを介してキャンセルされるため、割り込みに応答しないタスクは決して終了しない可能性があります。

これは待機中のタスクのリストを返します。これを完全に緩めるのではなく、常に「待機リスト」に戻すことができます。あなたはまた、逃げるコードを避けるために、それを「待っている」と待っているかもしれません。たとえば、executor.awaitTermination(...)です。

tempus-fugitには、これを処理するためのいくつかの便利なクラスがあります。電話するだけで

shutdown(executor).waitingForShutdown(millis(400)); 

hereを参照してください。

また、あなたはブログの記事で概要を説明しています。それが正しいかどうかは分かりません。 Future.cancelはタスクのスケジュールを停止するだけです。ブログで例を更新して割り込みを許可する場合は、shutdownNowと同等の(つまり、cancel(true))、それはinterruptを呼び出します。問題を解決するには、中断ポリシーの実装内で適切に対処する必要があります。結局のところ、shutdownNowを使用してのクリーンアップを正しくキャンセルすることができると思います。

+0

'shutdownNow()'メソッドはスケジュールされたジョブの 'Future.cancel()'を呼び出さない。実際には、 'Thread.interrupt()'メソッドでスレッドを中断するために専用の 'Worker'リストを使います。だから、私のデコレータは 'shutdownNow()'メソッドで呼び出されません。それに対して、 'shutdown()'メソッドはスレッドを中断することなく 'Future.cancel(false)'を呼び出すでしょう。したがって、実際には、パラメータ 'mayInterruptIfRunning = true'を実行してリソースを解放し、super.shutdownNow()を呼び出す前に' shutdownNow() 'を上書きしてFuture.cancel(true)を呼び出します。 – ggarciao

+0

問題は次のとおりです。私のカスタム 'shutdownNow()'メソッドで、すべてのジョブを正しく強制的に使用する必要のあるジョブリストはどれですか? 'getQueue()'メソッドを使うと、スケジュールされたものと定期的なものが得られます(そして、 'shutdown()'が呼び出されるとこのリストは空になるかもしれません)。しかし、実際に実行されているスレッドはどうですか? 'shutdownNow()'はそれらを中断しますが、どうすればそれらのリソースを解放することができますか?私は 'Future.cancel(true)'を呼び出すためにそれらへの参照が必要です。それに対して、私は他の答えで提案されているようにリストを保持します。これが最善の方法であるかどうかは分かりません – ggarciao

+0

私はなぜ電話をキャンセルするのかと言うのでしょうか?インタラプトよりもここで見た違いは何ですか?つまり割り込みでリソースを解放できる場合は、カスタムキャンセルは必要ありません。 – Toby

関連する問題