I want to build a very simple, yet efficient, scheduler to which classes that implement a SchedulerListener interface (for started/finished events) register with how many seconds and/or milliseconds must the scheduler wait to notify them (via the finished event).
When a request is finished, the individual object is notified and it calculates the difference between start and finishing times which are then compared to a previously registered "Expected time" so as to know the difference.
Usually differences vary between 0 to 20 milliseconds.
The issue is when differences are showed as negative - meaning the task finished before the time it was expected to have passed.
The scheduler runs on a separate Thread.
Does anything seem to be wrong with the code?
Note: originally the requests were stored in an ArrayList and the delays would go up to 30ms sometimes, but nothing bad at all. As an attempt to bring that value down i replaced the ArrayList with a ConcurrentHashMap (to avoid exceptions while iterating), which does bring down the delay though also causes the stated issue.
What I have tried:
The logic behind the scheduler is easy. Im using a Delta Time mechanic, decrementing each request (in milliseconds) by each "frame" 's deltaTime and unregistering the request after the respective time (or more) has passed.
I won't be posting all of the code to avoid overcluttering the question unless it's needed.
The Scheduler's code
public void registerListener(SchedulerListener listener, long seconds, long milliseconds)
{
if(!isRunning)
return;
listener.onSchedulerStart();
listeners.put(listener, secondsToMilliseconds(seconds) + milliseconds);
}
public void unregisterListener(SchedulerListener listener)
{
if(!isRunning)
return;
listeners.remove(listener);
public void run()
{
isRunning = true;
long lastTime, currentTime, deltaTime;
lastTime = System.currentTimeMillis();
while(!Thread.currentThread().isInterrupted())
{
currentTime = System.currentTimeMillis();
deltaTime = currentTime - lastTime;
checkRequests(deltaTime);
lastTime = currentTime;
}
}
private void checkRequests(long deltaTime)
{
long value;
for(SchedulerListener listener : listeners.keySet())
{
value = listeners.get(listener) - deltaTime;
listeners.put(listener, value);
if(value <= 0)
{
listener.onSchedulerDone();
listeners.remove(listener);
}
}
}