Multiple Timers handling

871 views Asked by At

I want to write a class that maintains many timers for different object with the ability to just notify or even run a task when timer is over, as well as to have the ability to cancel a timer.

For example if I have an object x of Type X with 3 Seconds timer that represents event E I want to be able to: 1. Know when it's over and do something about it 2. Cancel it if needed before it expires

I implemented something myself but I am sure libraries can offer much more.

I looked at ScheduledPoolExecutor but that doesn't really fit my needs for several reasons, like the fact that I might it to be single threaded and to be able to pass my "own" thread to it.

I also looked at Timer but it has a Thread in the background for every Timer instance and this is a big overhead I cannot allow.

Any ideas?

1

There are 1 answers

0
clearlight On

One of many possible solutions might be to make each object you want to time inherit from a superclass like Timeable, below (or define an interface or abstract class).

Have a single thread that is called once per second by a java Timer class. The timer's thread would access a list of your Timeable objects that it walks through and invokes the quantum() method on to deduct from their remaining time. Elsewhere setSecondsRemaining() is called to give the object a delta to timeout value, and add it to the list of objects being timed. If you want to cancel the timer on an object invoke it's cancelTimer() method.

If you need high accuracy of time then you need to consider the length of list of objects, how long it takes your timeout thread to walk that list and do some work to ensure that whatever time activity starts on your Timer thread that you complete all the work within one second and that you don't start before the next rounded second. Or you could use a different tick-tock value like 10 seconds. Many ways to handle that.

Below is just a rough example to help you understand the concept, but hasn't been compiled and obviously isn't the completed solution.

Base class (superclass):

public class Timeable {

    long secondsRemaining;

    Timeable() {}

    void setSecondsRemaining(long secondsRemaining) {
        self.secondsRemaining = secondsRemaining;
    }

    long getSecondsRemaining() {
        return secondsRemaining;
    }        

    void cancelTimer() {
        secondsRemaining = 0;
    }

    void subtractQuantum() {
        if (secondsRemaining == 0)
             return;
        if (--secondsRemaining == 0) 
             timeout();
    }

    void timeout() {
         // default timeout handling here - can be overriden by child
    }
}