Archive

Posts Tagged ‘timer’

Canceling and resume tasks with Timer and TimerTask in Java

February 5, 2014 No comments

We’ve been talking about using TimerTask and Timer to schedule tasks and passing arguments to these tasks for a more complex functionality. Today, we’ll be cancelling these periodic tasks (easy), but there are some problems when resuming, so I propose some ideas.

First, here is a basic code to cancel a task:
TimerEx.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.util.Timer;
import java.util.TimerTask;

class TimerEx
{
    public static void main(String arglist[])
    {
    Timer timer;
    timer = new Timer();

    TimerTask task = new TimerTask()
        {
        int tic = 0;

        @Override
        public void run()
        {
            System.out.println((tic++%2==0)?"TIC":"TOC");
        }
        };

    timer.schedule(task, 10, 100);
    try
        {
        Thread.sleep(1000);
        }
    catch (Exception e)
        {
        }
    task.cancel();
    }
}

In this example, the main program waits for a second (with Thread.sleep()) while the tasks is scheduled, so we will see the output running, and after that second, the process stops, but not exits because the Timer is still active. We can write “timer.cancel()”, the task is cancelling too and the program exists.

The problem comes when resumin this task after a while, because we have to create the TimerTask object again, if we try to reuse the old TimerTask (task) created, we’ll get an exception.

So, to cancel and resume, we can do it like this:
TimerEx.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import java.util.Timer;
import java.util.TimerTask;

class TimerEx
{
    public static void main(String arglist[])
    {
    Timer timer;
    timer = new Timer();

    TimerTask task = new TimerTask()
        {
        int tic = 0;

        @Override
        public void run()
        {
            System.out.println((tic++%2==0)?"TIC":"TOC");
        }
        };

    timer.schedule(task, 10, 100);
    try
        {
        Thread.sleep(1000);
        task.cancel();
        Thread.sleep(1000);
        }
    catch (Exception e)
        {
        }

    task = new TimerTask()
        {
        int tic = 0;

        @Override
        public void run()
        {
            System.out.println((tic++%2==0)?"TIC2":"TOC2");
        }
        };

    timer.schedule(task, 10, 100);
    }
}

But, as we must define the inner TimerTask class again, it’s interesting to create a separate derivate class. But let’s go further, we’ll make a TimerTask derivate that cancels and resumes itself, so our TimerTask (MyTimerTask) must know the Timer object, this way it can also re-schedule the task at different frequencies:

MyTimerTask.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.Timer;
import java.util.TimerTask;

class MyTimerTask extends TimerTask
{
    private int tic=0;
    private Timer timer;

    public MyTimerTask(Timer t)
    {
    this.timer = t;
    }

    public void run()
    {
    System.out.println((tic++%2==0)?"TIC":"TOC");
    if (tic%10==0)
        {
        System.out.println("Cancelling task");
        this.cancel();
        this.timer.schedule(new MyTimerTask(this.timer), 1000, 1000);
        }
    }
}

TimerEx.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.Timer;
import java.util.TimerTask;

class TimerEx
{
    public static void main(String arglist[])
    {
    Timer timer;
    timer = new Timer();

    TimerTask task = new MyTimerTask(timer);
    timer.schedule(task, 10, 100);
    }
}

But, as we can see, we must re-create the task object when re-scheduling, what about passing information between the old task to the new task? We may want that, for example, to know what has happened before the new task is created. To do that, we can create a store class, where we can use the attributes to store useful information between schedules, and we can pass this variable to our MyTimerTask constructor, but to avoid external classes to modify the values of our store class, this new overloaded constructor can be private.

In the next example, we just store an integer (we can store as many things as we want), and with this object we will control the times the task was canceled, and make it exit after 5 times:
MyTimerTaskInfo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class MyTimerTaskInfo
{
    private int times = 0;

    public void setTimes(int newTimes)
    {
    this.times = newTimes;
    }

    public int getTimes()
    {
    return this.times;
    }

    public void increment()
    {
    this.times++;
    }
}

MyTimerTask.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.util.Timer;
import java.util.TimerTask;

class MyTimerTask extends TimerTask
{
    private int tic=0;
    private Timer timer;
    private MyTimerTaskInfo info;

    public MyTimerTask(Timer t)
    {
    this.timer = t;
    this.info = new MyTimerTaskInfo();
    }

    private MyTimerTask(Timer t, MyTimerTaskInfo i)
    {
    this.timer = t;
    this.info = i;
    }

    public void run()
    {
    System.out.println((tic++%2==0)?"TIC":"TOC");
    if (tic%10==0)
        {
        System.out.println("Cancelling task");
        this.cancel();
        this.info.increment();
        if (info.getTimes()==5)
            {
            System.out.println("Exiting...");
            this.timer.cancel();
            }
        else
            this.timer.schedule(new MyTimerTask(this.timer, this.info), 200, 100);
        }
    }
}

TimerEx.java (not changed)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.Timer;
import java.util.TimerTask;

class TimerEx
{
    public static void main(String arglist[])
    {
    Timer timer;
    timer = new Timer();

    TimerTask task = new MyTimerTask(timer);
    timer.schedule(task, 10, 100);
    }
}

Passing arguments to a TimerTask in Java

January 17, 2014 No comments

I recently talked about using TimerTask in Java. Today we will pass variables or attributes to that TimerTask. We saw in the last article variable passing to an implicit or inner class, but now we’re creating a subclass and passing arguments through the constructor.

MyTimerTask.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.util.TimerTask;

class MyTimerTask extends TimerTask
{
    private int times;
    private String result;
    private int tic=0;

    public MyTimerTask (int times, String arg2)
    {
    this.times=times;
    this.result=arg2;
    }

    public String toString()
    {
    return result;
    }

    public void run()
    {
    System.out.println((tic++%2==0)?"TIC":"TOC");
    if (tic%times==0)
        result+="TEN! ";
    }
}

TimerEx.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Timer;
import java.util.TimerTask;

class TimerEx {
    public static void main(String arglist[]) {
    long lonlon=0;
    Timer timer;
    timer = new Timer();

    TimerTask task = new MyTimerTask(10, "Start: ");

    timer.schedule(task, 10, 1000);
    try
        {
        Thread.sleep(11000);
        }
    catch (Exception e)
        {
        }
    System.out.println(task);
    }
}

In this example, we’ve passed two arguments: 10, “Start: “, to the TimerTask (MyTimerTask) constructor, they will be the number of times the task must be launched before writing “TEN! ” on a String. On the other hand, we’ve implemented the method toString in MyTimerTask to write the value directly with System.out.println().

Easy, but, what about passing a callback to execute the System.out.println() ¿?

Let’s write an interface for the Callback (MyTimerCallback), then we will implement MyTimerTask and then we will make TimerEx implement MyTimerCallback, so we can put this function in the main class:

MyTimerCallback.java

1
2
3
4
interface MyTimerCallback
{
    public void timerCallback(MyTimerTask t);
}

MyTimerTask.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.util.TimerTask;

class MyTimerTask extends TimerTask
{
    private int times;
    private String result="";
    private int tic=0;
    private MyTimerCallback cbClass;

    public MyTimerTask (int times, MyTimerCallback cb)
    {
    this.times=times;
    this.cbClass=cb;
    }

    public String toString()
    {
    return result;
    }

    public void run()
    {
    System.out.println((tic++%2==0)?"TIC":"TOC");
    if (tic%times==0)
        {
        result+="TEN! ";
        cbClass.timerCallback(this);
        }
    }
}

Here, in the constructor, we are asking an object type MyTimerCallback, from which we will call timerCallback().

TimerEx.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.Timer;
import java.util.TimerTask;

class TimerEx implements MyTimerCallback
{
    public static void main(String arglist[])
    {
    long lonlon=0;
    Timer timer;
    timer = new Timer();

    TimerTask task = new MyTimerTask(10, new TimerEx());

    timer.schedule(task, 10, 1000);
    }

    public void timerCallback(MyTimerTask t)
    {
    System.out.println(t);
    }
}

From TimerEx, we pass a new TimerEx (as the main method is static and the class is not instanced, we must pass a new object).

Now, everytime 10 tics are executed, we will launch timerCallback(). And of course, we can do it as inner class (not instancing TimerEx, as we can see in the last example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.Timer;
import java.util.TimerTask;

class TimerEx implements MyTimerCallback
{
    public static void main(String arglist[])
    {
    long lonlon=0;
    Timer timer;
    timer = new Timer();

    TimerTask task = new MyTimerTask(10, new MyTimerCallback()
        {
        public void timerCallback(MyTimerTask t)
        {
            System.out.println("Inner class: "+t);
        }
        });

    timer.schedule(task, 10, 100);
    }

    public void timerCallback(MyTimerTask t)
    {
    System.out.println(t);
    }
}

[/cc]
Foto: Rob & Stephanie Levy (Flickr) CC-by

Introduction to Timer and TimerTask in Java

January 4, 2014 No comments

Timers are a useful tool to launch a task periodically, for example, if we are connected to a server, we can send status information to avoid disconnections, or launch a cron task, or even to run an animation (as the time goes by, we are changing a draw or a frame).

The most easy example can be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.util.Timer;
import java.util.TimerTask;

class TimerEx {
    public static void main(String arglist[]) {
    Timer timer;
    timer = new Timer();

    TimerTask task = new TimerTask() {
        int tic=0;

        @Override
        public void run()
        {
            if (tic%2==0)
            System.out.println("TIC");
            else
            System.out.println("TOC");
            tic++;
        }
        };
        // Start in 10ms and then, launch the task each 1000ms
    timer.schedule(task, 10, 1000);
    }
}

This program writes TIC and TOC alternatively each second, as the task is programmed each 1000ms. Is extremely easy, first, we must create a TimerTask object defining the task we want to launch inside the run() method (which we must @Override). Then, load a Timer and running the method schedule() we can call the desired task defining the time we want to wait before launching the first time and then the time we must wait before launching again the task.

If we only give one argument, the task will execute just once in N milliseconds. We can also specify Date objects in these arguments.

We can also call another schedule method called scheduleAtFixedRate, the difference is noticed when there are delays in executions (the tasks may be delayed due to other things in execution, instead of running each 1000ms, one task may be launched in 1500ms (because of these delays), scheduleAtFixedRate() will try to run the next task in 500ms to compensate lost time, but schedule() will run it after 1000ms, no matter if the task before was delayed.

The TimerTask in the example was created implicitly, it was an inner class, it’s absolutely valid for an example, or simple tasks. If we have something bigger it’s recommended to create a separate class for this task extending TimerTask superclass.

But, now the question is, how can we call an external variable? (External to the inner TimerTask we’ve created), call a variable of the main method of TimerEx. It has nothing to do with Timers but it’s interesting to tell:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.util.Timer;
import java.util.TimerTask;

class TimerEx {
    public static void main(String arglist[]) {
    Timer timer;
    timer = new Timer();
    final String str = new String("REACHED TEN TICS");

    TimerTask task = new TimerTask() {
        int tic = 0;

        @Override
        public void run()
        {
            if (tic%2==0)
            System.out.println("TIC");
            else
            System.out.println("TOC");
            tic++;
            if (tic%10==0)
            {
                System.out.println(str);
            }
        }
        };

    timer.schedule(task, 0, 1000);
    }
}

In this example, we’ve called the task ten times, and then str String will be written on screen. So inside inner or nested classes we can access final variables. But we can’t write them, because they are final. There is an scape, we can create a class allowing us to modify it’s attributes, so the value we are interested in can be changed. Let’s create a class TicClass to get tic attribute out of the nested TimerTask

TicClass.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class TicClass
{
    private int value;

    public TicClass(int initialValue)
    {
    this.value=initialValue;
    }

    public TicClass()
    {
    this.value=0;
    }

    public void setValue(int newValue)
    {
    this.value=newValue;
    }

    public int getValue()
    {
    return this.value;
    }

    public void increment()
    {
    this.value++;
    }
}

TimerEx.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.util.Timer;
import java.util.TimerTask;

class TimerEx {
    public static void main(String arglist[]) {
    Timer timer;
    timer = new Timer();
    final TicClass tic;
    tic = new TicClass(5);

    TimerTask task = new TimerTask() {
        @Override
        public void run()
        {
            if (tic.getValue()%2==0)
            System.out.println("TIC");
            else
            System.out.println("TOC");

            tic.increment();

            if (tic.getValue()%10==0)
            {
                System.out.println("TEN TICS!");
            }
        }
        };

    timer.schedule(task, 10, 1000);
    }
}

With this idea we can try to create a collection class to get some objects we want to change within the TimerTask and pass it as a final variable to the implicit class.

Photo: Andy Roberts (Flickr) CC-by

Top