2

In this example the author puts the main thread running a timer task to sleep before cancelling the timer task like this:

    System.out.println("TimerTask started");
    //cancel after sometime
    try {
        Thread.sleep(120000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    timer.cancel();
    System.out.println("TimerTask cancelled");
    try {
        Thread.sleep(30000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

After cancelling the author also puts it to sleep for another 30 seconds. Just curious why this is done? Is it only to show that the timer will still run even though the main thread is sleeping and are the additional 30 seconds added just to allow the timer a chance to cancel itself? Also is there another way to tell the timer to cancel after 120 seconds without putting the main thread to sleep?

Follow up

Great answer - just a follow up question to make sure I understand correctly- if the thread is non daemon and we cancel the first task after 2 minutes using the timer to schedule another task like you showed, will that then stop the main thread (As all tasks that were scheduled are now cancelled)?

Ole
  • 41,793
  • 59
  • 191
  • 359

1 Answers1

3

The code is demonstrative. The sleeps are there just to show the difference before and after cancelling the task. It waits two minutes to show the timer doing its work every 10 seconds, then it cancels the task and waits 30 seconds so you can see that it is no longer doing its work.

Also is there another way to tell the timer to cancel after 120 seconds without putting the main thread to sleep?

One option would be scheduling a second timer task to run after 120 seconds, whose runnable code just cancels the first task.

Timer timer = new Timer(false);

TimerTask firstTask = new TimerTask() {
    @Override
    public void run() {
        System.out.println("Hitme");
    }
};

timer.scheduleAtFixedRate(firstTask, 5000, 5000);
timer.schedule(new TimerTask() {
    @Override
    public void run() {
        firstTask.cancel();
    }
},45000);

You need to be careful though, because sometimes Timer and other scheduled executors run as daemon threads. If your main method finishes and the only threads left are daemon threads, the JVM will terminate regardless of whether there are pending tasks.

In the case of this example, the author is passing true to the constructor of Timer, which means it will be run as a daemon. If that is left unchanged, and the sleeps are removed, the JVM will exit immediately as the only remaining thread will be the daemon timer thread. The flipside of making it non-daemon is that your JVM will never exit unless some other thread cancels the Timer.

Edit

I just realized that TimerTask is not a lambda-compatible type, so the method reference doesn't work there.

Mark Peters
  • 80,126
  • 17
  • 159
  • 190