2013-01-20 6 views
42

私は倍.scheduleAtFixedRate(Runnable, INIT_DELAY, ACTION_DELAY, TimeUnit.SECONDS);ScheduledExecutorServiceからタスクを削除する方法は?

と定期的に、いくつかの異なるタスクは、私はまた私がこのスケジューラを使用してい異なるRunnableを持っていることをScheduledExecutorServiceを持っています。 スケジューラからタスクの1つを削除するときに問題が発生します。

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

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

答えて

63

は単にscheduledAtFixedRate()によって返された未来を取り消す:注意する

public static void main(String[] args) throws InterruptedException { 
    ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1); 
    Runnable r = new Runnable() { 
     @Override 
     public void run() { 
      System.out.println("Hello"); 
     } 
    }; 
    ScheduledFuture<?> scheduledFuture = 
     scheduledExecutorService.scheduleAtFixedRate(r, 1L, 1L, TimeUnit.SECONDS); 
    Thread.sleep(5000L); 
    scheduledFuture.cancel(false); 
} 

もう一つは、スケジューラからタスクを削除しないキャンセルことです。それは、isDoneメソッドが常にtrueを返すことだけです。このようなタスクを追加し続けると、メモリリークが発生する可能性があります。例:クライアントアクティビティまたはUIボタンのクリックに基づいてタスクを開始する場合は、n回繰り返して終了します。このボタンを何度もクリックすると、スケジューラに参照があるため、ガーベジコレクションできないスレッドの大きなプールになる可能性があります。

Java 7以降で使用できるScheduledThreadPoolExecutorクラスでは、setRemoveOnCancelPolicy(true)を使用することができます。下位互換性のために、デフォルトはfalseに設定されています。

+4

newSingleThreadScheduledExecutor()は、内部実行プログラムを公開していないので注意してください。自分で実行プログラムを作成し、プロパティを設定してからExecutors.unconfigurableScheduledExecutorService()でラップします。 –

+1

なぜ再利用できないのですか?キャンセルされたタスクを削除するのがなぜ難しいのですか? – JohnyTex

+0

'setRemoveOnCancelPolicy(true)'を使うには 'https://stackoverflow.com/a/36748183/3072570の' ScheduledThreadPoolExecutor'のインスタンス化のバリエーションの説明を参照してください。 – falvojr

0

あなたScheduledExecutorServiceインスタンスがThreadPoolExecutor(例えばScheduledThreadPoolExecutor)を拡張する場合は、remove(Runnable)を使用することができます(ただし、そのjavadocの注を参照してください:「それは内部キューに配置される前に他の形式に変換されたタスクを削除するために失敗することがあります。 」またはpurge())。

+0

このメソッドが 'Executor'に存在しなかった時、答えをくれてありがとう – thepoosh

関連する問題