2013-01-20 78 views
42

我有一個ScheduledExecutorService的那個時代的幾個不同的任務,定期用.scheduleAtFixedRate(Runnable, INIT_DELAY, ACTION_DELAY, TimeUnit.SECONDS);如何從ScheduledExecutorService中刪除任務?

我也有,我使用這個調度不同Runnable。 當我想要從調度程序中刪除其中一個任務時,問題就開始了。

有沒有辦法做到這一點?

我是否正在使用一個調度程序來處理不同的任務? 什麼是實現這個最好的方法?

回答

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。如果您不斷添加這些任務,這可能會導致內存泄漏。例如:如果您基於某些客戶端活動或用戶界面按鈕單擊來啓動任務,請重複執行n次並退出。如果單擊該按鈕的次數過多,則最終可能會導致大量線程無法收集,因爲調度程序仍有參考。

您可能希望在Java 7以後的ScheduledThreadPoolExecutor類中使用setRemoveOnCancelPolicy(true)。爲了向後兼容,默認設置爲false。

+4

注意到使用'newSingleThreadScheduledExecutor()'的人,因爲它不公開內部執行程序:自己創建一個執行程序,設置屬性,然後用'Executors.unconfigurableScheduledExecutorService()'包裝它。 –

+1

爲什麼我不能重用它?爲什麼很難取消取消的任務? – JohnyTex

+0

要使用'setRemoveOnCancelPolicy(true)',請參閱此處的'ScheduledThreadPoolExecutor'的實例化變體的解釋:https://stackoverflow.com/a/36748183/3072570。 – falvojr

0

如果您ScheduledExecutorService實例延伸ThreadPoolExecutor(如ScheduledThreadPoolExecutor),你可以使用remove(Runnable)(但看到音符在它的Javadoc:「很可能無法刪除已被放置在內部隊列之前已經轉換爲其他形式的任務。 「)或purge()

+0

謝謝你的回答,當時這個方法在'Executor'中不存在 – thepoosh