0

For the problem I am solving, I have to run a series of calls at periodic intervals. To achieve this, I have implemented TimerTask. However, I also want to notify the timertask sometimes and need to call the same methods when certain conditions are met even if the timer did not expire. My code looks similar to this.

//File TimerTaskA.java
public class TimerTaskA extends TimerTask
{
    @Override
    public void run()
    {
        processEvent1();
        processEvent2();
        processEvent3();
    }
}

//File ProcessEventManager.java
public class ProcessEventManager
{
    public TimerTaskA timerTask;

    public ProcessEventManager()
    {
        initTimerTask();
    }

    public void initTimerTask()
    {
        Timer timer = new Timer("TimerTaskA", true);
        timerTask == new TimerTaskA();
        timer.schedule(timerTask , 0, 10000);
    }

    public void conditionalTask()
    {
        long time = System.currentTimeMillis();
        // some condition statement. here it happens to be time in millisecs ends with 2 or 3.
        if (time%10 == 2 || time%10 == 3)
            timerTask.run();
    }
}

In the ProcessEventManager.conditionalTask() method is it correct to call TimerTask's run() method directly to get through this situation? Is there a better way design wise to solve something like this?

The processEvent methods might be time consuming methods, and I do not want the thread running ProcessEventManager to be blocked while executing those methods. For the TimerTask to take care of running those methods in both the cases when timer expires as well as the condition in ProcessEventManager.conditionalTask is satisfied, what is the best way to do it?

vk239
  • 1,014
  • 1
  • 12
  • 30

1 Answers1

1

Basically, yes, it is possible to do as you wrote, but a clearer way will be to call some processing method from inside the TimerTask, and when you want to perform this operation, call it directly, not through the TimerTask object.

public class TimerTaskA extends TimerTask
{

    public void doCoolThings()
    {
        processEvent1();
        processEvent2();
        processEvent3();
    }

    @Override
    public void run()
    {
        doCoolThings();
    }
}

in the other class, when needed:

timerTask.doCoolThings();

The reason as I see it, is mainly because the purpose of run is to serve as the thread (or caller) entry point, not to do a specific task.

MByD
  • 135,866
  • 28
  • 264
  • 277
  • Thank you for the quick answer. One reason I ask this question is, the `processEvent()` methods could be fairly time consuming. And I do not want the thread running `ProcessEventManager` to be blocked for the whole time. Is there a way I can notify the `TimerTask` to execute its `run()` when the required conditions are met apart from timer expiry? – vk239 Sep 11 '12 at 21:50
  • The problem with this, is that you need a thread to run it on. You can pass it to a new thread and start the new thread, as `TimerTask` implements `Runnable` – MByD Sep 11 '12 at 21:53
  • So that would be a new thread every time the condition in `ProcessEventManager.conditionalTask` is met. Can you please confirm if I understood correct? – vk239 Sep 11 '12 at 22:16
  • It could be, but a more efficient way to do that, if it is done many times, will be to create a thread that will wait for your notification (using object.wait() / notify() or similar mechanism) and execute the task when notified. – MByD Sep 11 '12 at 22:20
  • I am using a thread T1 with `wait()`/`notify()` to run the `doCoolThings()`. I have an additional timer task as well that notifies the thread T1 on timer expiry. Thanks for your help. – vk239 Sep 13 '12 at 17:54