Link to home
Start Free TrialLog in
Avatar of borg81
borg81

asked on

TimerTask change period at runtime

Is there a simple possibility to change the period of TimerTask at runtime?
I know that it can certainly be realised using a thread (sleep).
First I made it with threads and everything worked fine in the
Appletviewer. But when I tested it in a browser the applet was always
stopped with a messag from Security Manager that I have to modify thread and so on.
I tried everything in order to make it run with threads (Priority, ...) but it didn't work.
That's why I want it to do with TimerTask this time and it works so far...
Avatar of Mick Barry
Mick Barry
Flag of Australia image

There is no way to directly change the period of a task.
What you would do is cancel the task and start a new one with the desired period.
Avatar of keithfry
keithfry

The sad thing with Timer is that you cannot use the same TimerTask object. Below are two code snippets from the implementation of Timer.java & TimerTask.java (from JDK 1.3). When you call TimerTask.cancel(), you do indeed cancel the TimerTask. However you cannot use that task in any subsequent schedule operations as Timer.sched() will throw an IllegalStateException when the TimerTask is not a virgin. So if you take this approach, make sure that you create a NEW TimerTask object to set the period.

IMHO the Timer/TimerTask classes should be changed in the future to support:
* Timer: listing scheduled tasks by priority.
* Both: cooperate to allow cancelled tasks to be rescheduled.
* Both: allow adjusting period dynamically. This may include options for allowing the next scheduled run to occur or be pre-empted.

borg81: if you want to take a stab at it, you can always get a copy of the Java source, apply these changes as you see fit, TEST TEST TEST, and then triumphantly return with your improved Timer class. :-)



-----------
Timer.java
-----------
    private void sched(TimerTask task, long time, long period) {
        if (time < 0)
            throw new IllegalArgumentException("Illegal execution time.");
       
        synchronized(queue) {
            if (!thread.newTasksMayBeScheduled)
                throw new IllegalStateException("Timer already cancelled.");

            synchronized(task.lock) {
                if (task.state != TimerTask.VIRGIN)
                    throw new IllegalStateException(
                        "Task already scheduled or cancelled");
                task.nextExecutionTime = time;
                task.period = period;
                task.state = TimerTask.SCHEDULED;
            }

            queue.add(task);
            if (queue.getMin() == task)
                queue.notify();
        }
    }
-------------
TimerTask.java
-------------
    public boolean cancel() {
        synchronized(lock) {
            boolean result = (state == SCHEDULED);
            state = CANCELLED;
            return result;
        }
    }
--------------
ASKER CERTIFIED SOLUTION
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of borg81

ASKER

Thousand Thanks
no probs.
No drama, I just ran into that situation once and was confused with the error message.