[quote]Don’t use timer tasks or threads. Just write a simple scheduling class that performs things periodically (using System.currentTimeMillis() if that’s accurate enough) and is called once per iteration of your main loop.
[/quote]
Time to chime in with some recent experiences with TimerTasks…
They’re actually quite a nice idea, but leave you with the impression that the API was started by someone who left Sun shortly afterwards, and never quite finished the job. Apart from their flaws, they are very effective for tasks where your timing granularity is measured in large numbers of milliseconds.
They’re excellent for when you actually need to schedule things at “minutes past the hour” etc, because they can take a Date as the start time etc. This is also nice when you happen to be working in a multi-locale app, and being able to pass in Date’s without further worry is a relief (I HATE Date).
Unfortunately, they’re bloody dangerous. Witness the method: Timer.schedule( TimerTask t, Date starttime, long period ). starttime here is the Date (recall that Java names a time in milliseconds a “Date” Arggh!) that you want the task to be first scheduled. Period is, obviously, the period. This makes something like “every 5 minutes, offset = 2” (i.e. 7, 12, 17 etc) easy.
Except…The design of the API is such that if Date is in the past, it throws a runtime (i.e. your compiler won’t force you catch it) Exception. This is a disaster waiting to happen if you ever get pre-empted and by the time the method body is executed, that Date has passed…
Another PITA is that you cannot “reschedule( TimerTask )” nor - more usefully - “TimerTask.reschedule( blah blah blah )”. This means you have to keep explicitly cancelling your tasks, and maintaining extra state that is otherwise pointless, but for the fact that the API implementor didn’t quite get around to adding the reschedule method.
Anyway, my conclusion is that I’m continuing to use them as a quick-n-clean long-term scheduler that usually schedules in minutes, sometimes in seconds, and very rarely (…but this is really getting dangerous thanks to that Exception…) in millis. I know the problems with the API, and other than that it’s a bunch of code I don’t have to debug, that works quite nicely (note the easy integration with Runnable’s). Once I’ve got some extra time (or incoming staff :)) I’ll replace it with a slightly more feature-rich (and hence actually useful in practical situations!) task-scheduler (e.g. reschedule()). I’m also hoping that they’ll get deprecated and replaced in 1.5 with something more useful (I get the feeling that several improved clock/timer/scheduling things will appear pretty soon, probably all in one go)