Using less Timers - java

It doesn't really lag that much in my game but I know that I could reduce a lot of lag in my game by having less Timer's running. The game have multiple Timer's because it have one Timer that updates everything like the players location and all the obstacles then I have other Timer's that I use to remove the power ups that you could get.
For example I have one Timer that have it's initial delay set to 5000 and when it is runned one time (it will only run one time) it will remove a specific power up and the I have another Timer that have it's initial delay set to 20 000. How would I keep the different delay of each timer but still only using one or at least fever than I use now?
Is there anyway that I could use PriorityQueue or ScheduledThreadPoolExecutor to accomplish this? and if so how?

You would schedule tasks on the ScheduledThreadPoolExecutor, and then re-schedule them for a different delay if you want to run the same task again.
Another option is to use a DelayQueue to store the tasks you want to execute, and use a separate thread to take and execute runnables off of the queue. As with the ScheduledThreadPoolExecutor you'd have to put the runnables back on the queue with a new delay if you want them to run again.
The ScheduledThreadPoolExecutor lets you schedule tasks to continually run after a fixed delay, whereas the DelayQueue requires you to keep putting the task back on the queue after it's run.

Why would there be a timer that "updates everything"? Updating should always execute non-stop. (Unless you want to limit your game to constant FPS)
You really should consider abusing the "Game Loop":
While Game Is Running
Update()
Draw()
End While
If you don't want any lags in your game, you need to consider always updating player location, etc...
That said, when you update locations, etc... you need to make sure you make them relative to the time elapsed since last time Update() was executed.
If you're not constantly calling Update(), then you're going to have lags no matter what threading pattern you use.

Related

Is Executors.newSingleThreadScheduledExecutor() applicable for multiple objects?

Im making a small game where space-ships fire in intervalls of x seconds.
In this method Im spawning lasers the enemies can fire. In order to time their shots
Im using
Executors.newSingleThreadScheduledExecutor();
but Im not sure if that´s right when there can be multiple enemy-space ships on the board at once.
(Since its using one thread and then waits x seconds before using that thread for that task again).
So summarized: is this the right way to time an event for multiple objects or is it only working for one object a a time.
There are some more performance optimized versions, but the aproach is fine for the beginning.
ScheduledFuture<?> future = s.scheduleAtFixedRate(shoot, 0, enemy.getRate(), TimeUnit.SECONDS);
Will be scheduled once impediatly, and then every getRate() seconds until you call future.cancel().
Only one shot is evaluated at a single moment, thats fine if the caclculation is rather quick, and you don't call Thread.sleep() in the Runnable.

Why is there a need to use purge() of java.util.TimerTask?

Timer.cancel(): Cancels the task.
Timer.purge(): Remove all cancelled tasks from this timer's task queue.
What would happen when I would not use purge() here? What would happen when the timer's task queue got filled?
Nothing will change as to the actual Timer behaviour unless you have an ungodly number of timers going on. The cancel method does stop the timer running, but the program will still keep a reference to the timer even after its been cancelled, and so the memory it used will still be in use. The purge method allows Java to mark the timer references for garbage collection, allowing the memory they are using to be used for something else.
Most programs will not need to use the purge method, its just there for programs that will use a lot of timers, either many in a short burst, or if a program is going to be running for many days at a time.

Executing some code after a specific amount of time

I need to execute an action after a specific amount of time (for example 30 minutes after the app started up, if the app is still up).
What are my options and will it necessary means there's going to be one thread "lost" waiting for the 30 minutes to pass by?
Ideally, at program startup, I'd like to do something like the following (simplified on purpose) and then don't have to think about it anymore:
doIfStillUp( 30, new Runnable() {
....
});
So how should I go about implementing doIfStillUp(...)?
Should I use a TimerTask? The Executor framework?
Most importantly (it's for understanding purpose): does this mean there's going to be one thread lost idling for basically nothing during 30 minutes?
If there's going to be one thread "doing nothing", is this an issue? What if there are 10 000 threads (I'm being facetious here) "doing nothing"?
Note that I'm trying to understand the "big picture", not to solve a particular problem.
The Executor framework is a reasonable choice.
There's a schedule method that just takes a runnable and a delay time.
schedule(Runnable command,
long delay,
TimeUnit unit)
That's pretty straightforward. There won't necessarily be a thread blocked waiting on your task. You could use a ScheduledThreadPoolExecutor, as linked above that keeps X threads ready to run scheduled tasks.
You can imagine a data structure that holds the time at which a task should be run. A single thread can watch or set up these delays and can potentially watch thousands of them in a single thread. When the first time expires it'll run the task. Potentially using its own thread, potentially using 1 of X in the thread pool. When a new task is added or an existing task is finished it'll wait for the earliest time to arrive and then start the whole process again.
You should use a Timer. Its javadoc answers all your questions.
One thread is used for every timer, but the timer executes several tasks, sequentially. The timer tasks should be very short. If they aren't, consider using several timers.
Of course, the timer thread will be idle if it doesn't have any task to execute. An idle thread doesn't consume anything (or nearly anything), so I wouldn't worry about it. Anyway, you don't have many choices. 10000 threads doing nothing would of course be an issue, but that would mean that you instantiated one timer per task, which is wrong.
You can schedule task on java.util.Timer. For all timer tasks single timer thread will be created by java.util.Timer.
The builtin java timer is the straight away solution: http://download.oracle.com/javase/1,5.0/docs/api/java/util/Timer.html#schedule(java.util.TimerTask, long)

How do I make sure a Timer stays alive?

I have code that relies on a Timer staying alive and managing TimerTask. Usually TimersTasks will come and go and there will always be at least one TimerTask to keep the Timer alive, but every now and then all the TimerTasks will die and the Timer will die with it.
How would I keep Timer alive? Should I have one TimerTask in it at scheduled to fire at a far away date? That's what I'm leaning towards, but I want to hear what more experienced programer's ideas would be.
*It would also be nice if I could terminate all TimerTaks except for this one 'permanent' TimerTask.
Sorry if none of this makes much sense, or if I'm thinking of Timers and TimerTasks all wrong. I'm brand new to Java and all programming.
This sounds backwards. The Timer is the thing that manages the tasks. The TimerTask is the thing that is getting managed. You create a timer, you tell it to schedule the timertask, which can be singular or continuous (e.g. you can set the task to run every hour for as long as your JVM is running). It will run until it has no more tasks.
From the docs:
After the last live reference to a Timer object goes away and all
outstanding tasks have completed execution, the timer's task execution
thread terminates gracefully (and becomes subject to garbage
collection).

Detect if system time has been moved backwards in java, or time proof timers

I have a box thats using ntp and we have several java programs running on them that display a clock. The problem we are having is if anything kicks the system time backwards all our timers that do things like animate the clock stop and wait until the system time catches back up to where it was. I need to find a way to either detect when the system time has been changed backwards and reset all our timers or a set of timers that can schedule repeatedly but still be proof against the clock changing.
As a note I already tried the quartz timer package it has the same problem as the regular java timers.
Pretty much all timers set a future time and then regularly compare current time to the given time. That's why timers "stall" when real time goes backward.
Unfortunately, ALL of the timers in the JVM are related to the time of day. For example, java.util.Timer does a Object.wait(milliSeconds) for an event to fire. That boils down to a thread call that also does a wait, for t milliseconds. And it's always relative to the "time of day".
So, basically there's no real way to do this in java without a spinning, CPU sucking loop waiting for the time to go backward in order to inform the timers you care about to reset.
It sounds like the clock widget is what's broken. A UI widget should display the current state of the model, where the model, in this case, is the system time. Sure, for a clock, you'd need to schedule a repaint() every second, but when the repaint occurs, it should render the system time, not try to keep track of the time itself.
This principle would apply even to non-UI components. Determine the tolerance of the component to timing errors, and have a background thread that refreshes the component at that interval. During a refresh, however, the system time is used, not an independent, internal clock.
Update:
The basic ScheduledExecutorService doesn't suffer from this problem, at least on my platform.
ScheduledExecutorService worker = Executors.newScheduledThreadPool(1);
worker.schedule(new Runnable() {
public void run()
{
update();
}
}, 100, TimeUnit.MILLISECONDS);

Categories

Resources