scheduleAtFixedRate(Runnable, INIT_DELAY, ACTION_DELAY, TimeUnit.SECONDS);
で定期的にいくつかの異なるタスクを実行するScheduledExecutorService
があります
また、このスケジューラで使用している別のRunnable
もあります。スケジューラからタスクの1つを削除するときに問題が始まります。
これを行う方法はありますか?
異なるタスクに1つのスケジューラを使用して正しいことをしていますか?これを実装する最良の方法は何ですか?
scheduledAtFixedRate()
によって返される未来を単にキャンセルします。
_// Create the scheduler
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
// Create the task to execute
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("Hello");
}
};
// Schedule the task such that it will be executed every second
ScheduledFuture<?> scheduledFuture =
scheduledExecutorService.scheduleAtFixedRate(r, 1L, 1L, TimeUnit.SECONDS);
// Wait 5 seconds
Thread.sleep(5000L);
// Cancel the task
scheduledFuture.cancel(false);
_
もう1つ注意すべきことは、キャンセルしてもスケジューラからタスクが削除されないことです。 isDone
メソッドが常にtrue
を返すことだけが保証されます。このようなタスクを追加し続けると、メモリリークが発生する可能性があります。例:クライアントのアクティビティまたはUIボタンのクリックに基づいてタスクを開始する場合、n回繰り返して終了します。そのボタンが何度もクリックされると、スケジューラにまだ参照があるため、ガベージコレクションできないスレッドの大きなプールになる可能性があります。
Java 7以降で利用可能なScheduledThreadPoolExecutor
クラスでsetRemoveOnCancelPolicy(true)
を使用することができます。後方互換性のために、デフォルトはfalseに設定されています。
ScheduledExecutorService
インスタンスがThreadPoolExecutor
を拡張している場合(たとえばScheduledThreadPoolExecutor
)、remove(Runnable)
を使用できます(ただし、javadocの注意を参照してください。内部キューに配置される前に他のフォームに変換されたタスクを削除します。 ")またはpurge()
。