Advanced Java: Scheduling Multiple Tasks…
In the previous article, we have seen the usage of Timer
and TimerTask
using a small real-world problem. Let's talk more about the same program.
Scheduling a Task
Timer.schedule()
method is used for scheduling a task.- This method takes two arguments the first one is an instance of a class which extends the
TimerTask
class the second argument is the wait time or delay in milliseconds. - Once the wait time is over the timer execute the task.
But how does this work?
- The
Timer
class uses a thread and a priority-based task queue internally. - As soon as we create the timer, they get initialized and the thread starts the execution.
- The thread keeps waiting for new tasks in the queue.
- Whenever the user schedules a new task by calling the schedule method, this will get added to the queue.
- Once a new task is available or an ongoing task is finished, the thread picks up the next task based on some constraints (This is out of scope and we won’t discuss here).
- If the task picked up by the thread is qualified for execution, the
run()
method of task gets called and so it starts the execution.
The qualification check is done by the thread with the help of the priority task queue. The delay time passed here is one of the constraints for this.
This implies that even if you schedule 100 tasks sequentially with different delays or wait times, the order of task execution may vary.
Code
Once you run the above program, we can notice that the execution order varies.
Cancelling Timer
- When we call
cancel()
method on the timer, the priority task queue associated with theTimer
will be cleared. - If there are any pending tasks they will be ignored.
- If the timer is canceled from the scope of a
run()
method of a task which is currently being executed by this timer thread, it will not stop the task. - This guarantees that the ongoing task execution will get finished before the timer gets canceled.
- Calling
cancel()
on a timer stops the internal thread and so calling it multiple times after the first time has no effect.
@Override
public void run() {
if (this.id.equals("D")) {
// Calling cancel() here will remove other pending tasks.
// But it completes task D.
timer.cancel();
}
System.out.println("Task " + this.id + " has been completed.");
}
Canceling a Task
Yeah, like Timer, we can cancel TimerTask
too. Take a look at below lines of code
- We can cancel a task that is in pending execution (still in the queue, not picked up by the thread).
- Calling
cancel()
from within the executing task doesn't stop the execution but prevents the repeated executions, if this task is scheduled for repeated execution.
The below-given scenario doesn’t have any effect.
@Override
public void run() {
// This doesn't have any effect.
//if (this.id.equals("B")) {
// this.cancel();
//}
System.out.println("Task " + this.id + " has been completed.");
}
The below-given scenario is correct
this.timer.schedule(new SimpleTask("D"), 1500);
TimerTask e = new SimpleTask("E");
this.timer.schedule(e, 10000);
e.cancel();
this.timer.schedule(new SimpleTask("F"), 2000);
This will change the task E’s state to canceled and won’t be picked up by the thread.
That’s it. Hope you understood the things we discussed. Please let me know your queries and suggestions 🙂
Happy Coding!
Seyed F
Originally published at http://sydlabz.wordpress.com on September 4, 2019.