Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When a Java TimerTask is scheduled in a Timer, is it already "executing"?

I would like to clarify something about TimerTask. When you have the code below:

timer.schedule(task, 60000);

where the task is scheduled to run in the next 1 minute, is the task object already executing?

because somewhere in my code I called task.cancel() but it seems that the call doesn't prevent

task to be executed. I even logged the return value from the call and it returns false.

I came about my question when I read the documentation for the cancel method:

Cancels the TimerTask and removes it from the Timer's queue. Generally, it returns false if the call did not prevent a TimerTask from running at least once. Subsequent calls have no effect. Returns true if the call prevented a scheduled execution from taking place, false otherwise.

I believe I called cancel() before the 1 minute delay. But how come cancel returned false,

is it [task] already executing?

Hope you can give me clues/hints or even an explanation to this. Thanks SO!

like image 514
Randy Martinez Avatar asked Nov 10 '11 03:11

Randy Martinez


People also ask

What is the relationship between Timer and TimerTask?

Timer and TimerTask are java util classes that we use to schedule tasks in a background thread. Basically, TimerTask is the task to perform, and Timer is the scheduler.

How does Java Timer work?

A Timer in Java is a process that enables threads to schedule tasks for later execution. Scheduling is done by keeping a specific process in the queue such that when the execution time comes, the processor can suspend other processes and run the task.

Does Java Timer create a new thread?

There it states: "Corresponding to each Timer object is a single backgroundthread that is used to execute all of the timer's tasks, sequentially." - so yes, each Timer has its own thread but if you schedule 2 tasks on the same timer they will be executed sequentially.

How do you schedule a Timer in Java?

Java Timer schedule() methodThe schedule (TimerTask task, Date time) method of Timer class is used to schedule the task for execution at the given time. If the time given is in the past, the task is scheduled at that movement for execution.


2 Answers

  • where the task is scheduled to run in the next 1 minute, is the task object already executing

No, it is going to invoke the run method of this task in exactly 60 seconds. If task.cancel() returns false, that could mean 3 things:

  • the task was scheduled for one-time execution and has already run OR
  • the task was never scheduled OR
  • the task was already cancelled OR

Hence, if you are certain that you call cancel before 60 seconds after scheduling the task, you could potentially either call it several times, and get a result from a subsequent cancel, OR you are calling cancel on a different task.


In general, I would recommend against Timer in favor of a ScheduledExecutorService

You can achieve a desired functionality with:

ScheduledExecutorService.schedule( callable, delay, timeunit )

Reasons why ScheduledExecutorService are is a preferred way are outlined here:

  • Timer can be sensitive to changes in the system clock, ScheduledThreadPoolExecutor isn't

  • Timer has only one execution thread, so long-running task can delay other tasks. ScheduledThreadPoolExecutor can be configured with any number of threads. Furthermore, you have full control over created threads, if you want (by providing ThreadFactory)

  • runtime exceptions thrown in TimerTask kill that one thread, thus making Timer dead :-( ... i.e. scheduled tasks will not run anymore. ScheduledThreadExecutor not only catches runtime exceptions, but it lets you handle them if you want (by overriding afterExecute method from ThreadPoolExecutor). Task which threw exception will be canceled, but other tasks will continue to run.

like image 118
tolitius Avatar answered Oct 16 '22 21:10

tolitius


I don't know why your code returns false.

The following code prints true.

import java.util.Timer;
import java.util.TimerTask;


public class Test {
    public static void main(String[] args) {
        Timer timer = new Timer();
        TimerTask task = new TimerTask() {

            @Override
            public void run() {
                System.out.println("hi");
            }

        };
        timer.schedule(task, 60000);
        System.out.println(task.cancel());
    }
}

If the last println is commented, the program prints hi.

like image 42
wannik Avatar answered Oct 16 '22 22:10

wannik