Synchronising multiple timers to step up/down speed
I have several instances in my application. Each of these instances have a Timer object which will trigger the object's own method after an amount of time.
As this would be a simple simulation app, I intend to allow it to have a pause/continue simulation feature as well as an "step up/down speed" feature to the timers.
However, if all my instances have their own individual Timer objects, they will all run independently开发者_运维问答 on their own and it is difficult to ask all these objects to pause and then continue. Even if I were to loop through a list of array to call every instances to pause/continue its timer, this definitely isn't a very efficient way to do things. This same problem applies for stepping up and down the overall speed of the timers.
It seems like I should have only one single timer in the simulation world that will control all of the instances but again, this would make things very complex as well.
What are some of the implementation methods to achieve such requirements? I am using Java for my application.
Thanks!
You could always use an event-driven approach. Have each object register as a listener of the main controller and when an option is changed, just trigger an event and let all of the instances update themselves.
I'd definitely suggest going with one central timer. In addition, you could have one centralized ArrayList
where you can register all objects that need to be triggered by the timer. The objects could implement an interface, say, ITimerInvokeable
, with a method timerTick()
or something along those lines. When the timer ticks, it can loop over the ArrayList
and call timerTick()
on all objects. Computationally, this isn't more expensive than having a timer in each object, since you'll end up with the same number of method calls (and the loop overhead is minimal). In addition, you'll save resources because you don't have a ton of timers running.
(This is an event-driven approach and looks similar to @Kyle's answer, but as far as I can tell, he proposes to use the events to propagate the changes in the timer information.)
As it's a simulation, maybe there is a better way than launching a bunch of Timer
s? Perhaps you could have a single representation of "time" that can notify listeners (or more simply a list) after some preset amount of time.
So, if your Timer
should go off after 5 seconds, then that unified time holder would notify your object after 5 ticks of its "time."
Then, you could have one timer that simply executes at whatever granularity that you need (e.g., 1 second represents 1 tick). That way, if you need to speed up or slow down the simulation, then after that single Timer
goes off, then you increment the "ticks" rather than a real time. So, 50% speed only goes up 0.5 ticks each second. 200% speed goes up 2 ticks each second.
A centralised timer is the best way, but I wouldn't do this for efficiency reasons but because it would simplify ensure centralised control.
One way to centralise these timers is to use a PriorityQueue. You can add each Timer to the priority Queue and repeatedly get the next Timer from the Queue. For repeating tasks, add to the queue again. You can play these events at any rate you wish. ;)
You can call a method across ten thousand objects in a fraction of a milli-second. If that's is all you are worried about, perhaps you don't need to change.
Kinda depends on how many timers you need. You could certainly implement a list of timeout-objects with 'OnTimeout' events that one, centralized timer handles. One question is - is it worth ordering the list by timeout-time? If insert/remove/changeTimeout operations are few, and the number of 'timers' is large, you could keep the list ordered and the timer would only need to time out the item at the head of the list. One high-resolution timer could then handle hundreds of 'timers' with high accuracy. The downside is that insert/remove/changeTimeout requires re-ordering the list. In addition, if the timers repeat like system timers, a fired timer has to be put back on the list - another insert operation :(
Not sure if your app justifies this kind of delta-queue complexity.
Rgds, Martin
精彩评论