73

私はScheduledExecutorService定期的にいくつかの異なるタスクを持っていますscheduleAtFixedRate(Runnable, INIT_DELAY, ACTION_DELAY, TimeUnit.SECONDS);

Runnableまた、このスケジューラーで使用しているものとは異なります。スケジューラーからタスクの1つを削除したいときに問題が始まります。

これを行う方法はありますか?

さまざまなタスクに1つのスケジューラーを使用して正しいことをしていますか?これを実装するための最良の方法は何ですか?

4

2 に答える 2

112

によって返された未来を単にキャンセルします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 以降で使用可能なクラスで使用setRemoveOnCancelPolicy(true)することができます。ScheduledThreadPoolExecutor下位互換性のために、デフォルトは false に設定されています。

于 2013-01-20T10:26:33.480 に答える