Waiting for timer to end in Java

I use java.util.Timer to schedule a periodic task. At some point, I would like to close it and wait for it to finish .

Timer.cancel () will prevent any future tasks from starting. How can I make sure that any tasks are not currently running (or wait for them, if any?)

I can imagine external synchronization mechanisms, but I don’t see how they can cover all cases. For example, if I synchronize on some monitor inside the task, I will still miss the case when the task just started, but did not take the monitor.

What is the recommended practice for waiting for all tasks to be completed, including currently running tasks?

+7
java synchronization timer monitor
source share
2 answers

It is better to use a ScheduledExecutorService instead of a timer to schedule a periodic task. ScheduledExecutorService provides a shutdown () method that will execute any pending tasks. You can then call waitTermination () to wait for shutdown () to complete.

+18
source share

Something like below might help your needs -

import java.util.Timer; import java.util.TimerTask; public class TimerGracefulShutdown { public static void main(String[] args) throws InterruptedException { //This is a synchronization helper class SyncHelper syncHelper = new SyncHelper(); TimerManager myTimerManager = new TimerManager(syncHelper); //Try stopping timer after 5 seconds (it wont stop until the 30 seconds sleep of timertask does not finish) Thread.currentThread().sleep(5000); System.out.println("Going to stop my timer now"); myTimerManager.stopTimer(); System.out.println("Cancelled timer"); } } class TimerManager { SyncHelper syncHelper; Timer timer; public TimerManager(SyncHelper syncHelper) { this.syncHelper = syncHelper; startTimer(); } private void startTimer() { timer = new Timer(true); TimerTask myTask = new MyTimerTask(syncHelper); timer.scheduleAtFixedRate(myTask, 0, 100000); } public void stopTimer() { try { syncHelper.testAndSetOrReset("acquire"); } catch(Exception e) { e.printStackTrace(); } //Shutdown the timer here since you know that your timertask is not executing right now. timer.cancel(); try { syncHelper.testAndSetOrReset("release"); } catch (Exception e) { e.printStackTrace(); } } } class MyTimerTask extends TimerTask { private SyncHelper syncHelper; public MyTimerTask(SyncHelper syncHelper) { this.syncHelper = syncHelper; } public void run() { try { syncHelper.testAndSetOrReset("acquire"); } catch (Exception e1) { e1.printStackTrace(); } System.out.println("Over here"); try { Thread.currentThread().sleep(30000); } catch(Exception e) { } System.out.println("Done sleeping"); //Finally release the helper. try { syncHelper.testAndSetOrReset("release"); } catch (Exception e) { e.printStackTrace(); } } } class SyncHelper { private int index = 0; public synchronized void testAndSetOrReset(String command) throws Exception { if("acquire".equals(command)) { if(index == 1) { wait(); } index++; } else if("release".equals(command)) { index--; notifyAll(); } } } 
0
source share

All Articles