Several TimerTasks or just one?

Hi,

I’d like to do several timed tasks in a game. Task ExA shall be issued every second, task ExB 10 times a second, etc.
What’s more efficient: to use several TimerTask classes for each of them (they run in an own Thread then) or to use one TimerTask class which internally does all the different tasks, controlled by variable counters?


class ExA extends java.util.TimerTask
{
  run() {..}
}

--

java.util.Timer timer = new java.util.Timer();
timer.schedule(new ExA(), 1, 1000/ 1);  // Call it  1 times a second.
timer.schedule(new ExB(), 1, 1000/10);  // Call it 10 times a second.
timer.schedule(new ExC(), 1, 1000/20);  // Call it 20 times a second.

In former times (C/C++) I used one timer which did all stuff by using counters.
However, how are things in Java today? Is there a big overhead to create severak small TimerTasks, or is Thread handling in Java a totally natural and lightning fast operation?

While the different TimerTasks are much more elegant to implement, I’m afraid it involves an overhead which I don’t like. :slight_smile:

Thanks.

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.

Cas :slight_smile:

Why don’t use Threads ??? ? I tested Threads/Timers and I see the following :
Thread: 5% CPU Load
Timer: 100% CPU Load (With the hidden Perf-Thingie)

Troggan

Games have 100% CPU load, its a must have, the System will never go to sleep mode or reduce CPU speed.

Check some games ( like Ultima Online ), when i start it in a window i have 100% CPU load.

So u get 100% of the CPU, u want a Realtime Game, so u need all the power u can get 8)

Threads in java is supposed to be ligthweight. So there should be very little performance overhead in using 3 threads instead of 1.

Under Win9x threads are scheduled by the timer which has a 50ms resolution. So maximum FPS will be 20FPS if u go higher your game will flicker and lag, trust me i am a professional game developer.

Next Problem with Threads are the synchronized things, even if u do the game physics in multiple threads you have to sync to render method, otherwise you will change variables in the middle of a render.

I use my own pseudo Thread scheduler, i called it a GameEvent.

Those GameEvents have a counter ( how many times should the Event be called ) and a delay ( how many time between calls to Event )

I have 1 Vector with all events, i put a event for a scroller in it, it gets called every 50ms and the counter is -1 which means it will never expire.

I get a very very smooth scrolling with it.

Threading might not have a huge overhead, but writing thread safe code is a LOT harder than just going with one thread.

And considering you only benefit from using multiple threads when doing blocking IO operations or using a multi-processor system, there’s really not much speaking for multi-threading any more.

Not that I disagree in this case, but threading can often help in modular code design. If you have two sections of your code that logically run at the same time then using two threads can often make the code far easier to comprehend and if the interface between these two section is clearly defined then synchronisation isn’t really that much of a difficulty.

However, since we’re in “Performance Tuning” threading is pretty much a no no.

The CPU usage thing is a red herring, the 100% usage fades away as other things want to use the processor. It just makes sense for game that if they can get 100% of the CPU time, to take it. :slight_smile:

Kev

[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)

One step at a time:

"Thank you for reporting this issue.

We have determined that this report is a new bug and entered the bug into our
internal bug tracking system under Bug Id: 4923634

synopsis : TimerTask should be an interface, or else take an interface as argument
description : A DESCRIPTION OF THE REQUEST :
TimerTask needs an additional constructor, which takes a Runnable as argument.

Add an extra constructor to TimerTask that takes a Runnable as argument. (this guarantees that the class has a .run() method EXACTLY as per TimerTask)"