2013-01-20 8 views
42

Mam ScheduledExecutorService że czasy kilka inne zadanie okresowo .scheduleAtFixedRate(Runnable, INIT_DELAY, ACTION_DELAY, TimeUnit.SECONDS);Jak usunąć zadanie z usługi ScheduledExecutorService?

Mam też inną Runnable że używam z tego harmonogramu. Problem zaczyna się, gdy chcę usunąć jedno z zadań z harmonogramu.

Czy istnieje sposób, aby to zrobić?

Czy robię to, co trzeba, używając jednego harmonogramu do różnych zadań? jaki jest najlepszy sposób wdrożenia tego?

Odpowiedz

63

Wystarczy odwołać przyszłość zwrócony przez 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); 
} 

Inną rzeczą, aby pamiętać, że nie anulować usunięcie zadania z harmonogramu. Wszystko to zapewnia, że ​​metoda "zawsze" zawsze zwraca wartość "prawda". Może to prowadzić do wycieków pamięci, jeśli nadal dodajesz takie zadania. Na przykład: jeśli uruchamiasz zadanie w oparciu o jakąś aktywność klienta lub przycisk UI, kliknij, powtórz to n-razy i zakończ. Jeśli ten przycisk zostanie kliknięty zbyt wiele razy, możesz skończyć z dużą pulą wątków, które nie mogą być zbędne, ponieważ program planujący nadal ma odniesienie.

Możesz użyć setRemoveOnCancelPolicy (true) w klasie ScheduledThreadPoolExecutor dostępnej w Javie 7 lub nowszej. Ze względu na kompatybilność wstecz, domyślnie ustawiona jest na false.

+4

Uwaga dla osób używających 'newSingleThreadScheduledExecutor()', ponieważ nie ujawnia wewnętrznego executora: Utwórz executor samodzielnie, ustaw właściwość, a następnie owiń ją 'Executors.unconfigurableScheduledExecutorService()'. –

+1

Dlaczego nie mogę go ponownie użyć? Dlaczego tak trudno usunąć anulowane zadania? – JohnyTex

+0

Aby użyć 'setRemoveOnCancelPolicy (true)', zobacz wyjaśnienie wariantów wystąpienia dla 'ScheduledThreadPoolExecutor' tutaj: https://stackoverflow.com/a/36748183/3072570. – falvojr

0

Jeśli instancja ScheduledExecutorService rozciąga ThreadPoolExecutor (np ScheduledThreadPoolExecutor), można użyć remove(Runnable) (ale patrz uwaga w javadoc: „Może to nie do usunięcia zadań, które zostały zamienione na inne formy przed umieszczeniem w kolejce wewnętrznej. ") lub purge().

+0

dzięki za odpowiedź, w chwili, gdy ta metoda nie istniała w 'Executorze' – thepoosh

Powiązane problemy