I am working on a Java program and using Timer objects to run tasks every few minutes or hours. This works fine in normal operations, but I am running into a problem with "Sleep mode" on Mac (maybe on other OSes, but I haven't tried yet).
Consider this code sample:
//Setup the timer to fire the ping worker (every 3 minutes)
_PingTimer.scheduleAtFixedRate(new TimerTask(){
public void run(){
Program.PingThread = new PingWorker(Settings.Username, Settings.UserHash, true, true);
Program.PingThread.CheckOpenPort = true;
Program.SwingExecutor.execute(Program.PingThread);
}
}, 0, 180000);
In normal operation this would fire every 3 minutes with enough accuracy (I'm not concerned about the exact second or anything). The problem with this is after sleeping the computer for a few hours or so it seems to just BLAST the system with backlogged timer requests.
It seems to be running all of the missed timer hits during sleep at once trying to make up for lost time.
Is there a way i can prevent this? I tried using synchronized and some other thread techniques, but this only ensures that they aren't all running at the same time. They still continue to run one after another until the backlog is passed.
Thanks for any help you can provide!
Have you looked at the API? It clearly states the following:
In fixed-rate execution, each
execution is scheduled relative to the
scheduled execution time of the
initial execution. If an execution is
delayed for any reason (such as
garbage collection or other background
activity), two or more executions will
occur in rapid succession to "catch
up." In the long run, the frequency of
execution will be exactly the
reciprocal of the specified period
(assuming the system clock underlying
Object.wait(long) is accurate).
This is one reason why you should consider using a ScheduledExecutorService. This link may also prove useful.
Use schedule instead of scheduleAtFixedRate.
Related
I am using my java program to control a motor via Arduino. I plan to introduce the delays in the software itself and not in Arduino. How can I accurately do that since introducing delays using thread.sleep() is very inaccurate? Additionally, I want to pause the delay and upon resume, I want the software to complete the rest of the delay. For example, if I kept a delay for 1000 milliseconds and pause at 700 milliseconds, I want to stop the motor; upon resume, I want to finish the rest of the 300 milliseconds. How efficient it would be if I use a while loop till the System.currentTimeMillis() reaches a specific amount of time?
Make use of ScheduledThreadPoolExecutor. ScheduledExecutorService is an executor service that allows you to schedule future and recurring asynchronous tasks in Java.
It has been observed that long/ recurring tasks executed using ScheduledExecutorService can result in Memory Leaks. Since Java 7, ScheduledThreadPoolExecutor exposed a new method setRemoveOnCancelPolicy. Make sure this flag is set, as a precautionary measure.
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
// Explicitly call setRemoveOnCancelPolicy on the instance
executor.setRemoveOnCancelPolicy(true);
As per javaDoc, setRemoveOnCancelPolicy sets the policy on whether cancelled tasks should be immediately
removed from the work queue at time of cancellation. This value is by
default false
I'm programming a game in Java and I limit the FPS to 60. I figured out 2 different ways to get the same result, but I'm wondering which of them is the better/cleaner way to do it. Or maybe you have a different idea.
while(System.nanoTime() - thisFrame < fps_limit);
or
Thread.sleep(sleepingTime);
My thinking is that the while loop effects the CPU more than Thread.sleep, am I right?
Thanks in advance for your help!
Dom
You have the following main options:
While loop - This will consume CPU cycles and often will actually stop the system because while you are looping, other threads cannot run (on a one-core machine).
Thread.sleep() - This can be effective but you need to remember that is not guaranteed to wait the specified time.
DelayQueue - More up-to-date. Better/accurate timing.
ScheduledThreadPoolExecutor - Still more up-to-date than DelayQueue. Uses a Thread Pool.
You're right, while both with achieve what you're trying to do, the while loop will keep the processor occupied, consuming CPU time.
In contrast, Thread.sleep() frees the processor for the amount of time mentioned.
So, Thread.sleep() is better.
Both the answers posted already are good - sleep is better than loop. However, you can go into much more detail about how to write a good loop. If you are interested, here is a great resource: http://www.java-gaming.org/index.php?topic=24220.0
It covers topics like variable timestep and interpolation, which can be used to make your graphics run extremely smoothly. This solves the issues Thread.sleep has with not being 100% accurate in its timing as well as preventing your graphics from appearing jerky if your game performs some calculation that takes some time.
What I would do (pseudo code).
//timepast since last loop in ms
timepast = 0
fpslimit = 60
finished = true;
//while the game is running
while(runnning)
{
timepast += timeSinceLastrun
if(timepast > 1second/fpslimit && finished)
{
finished = false
dostuff(timepast)
}
//sleep for the time of 1second/fpslimit - timepassed to avoid cpu blocking
Thread.sleep((1second/fpslimit) - timepast )
}
dostuff(deltatime)
{
//do stuff in the end after it finished set
//finished to true so dostuff can be called again
finished = true
timepast=0
}
In this way you can easily limit the fps with a variable and dont need to block other threads.
as OldCurmudgeon said thread.sleep dosnt block other threads in java and make processor time available.
Thread.sleep causes the current thread to suspend execution for a
specified period. This is an efficient means of making processor time
available to the other threads of an application or other applications
that might be running on a computer system
Also you can pass timepast to the dostuff method as a deltatime so the game runs the same on all devices (same speed).
I concur with #ayush - while loops are usually blocking functions, whereas threads are more like interrupt-driven or parallel programming functions. I'm a bit green on Java, but could you not setup a timer rather than sleeping?
Yeah it looks like Timer constructs, like in C++, are available. Check this out: Timer in Java Thread
You should use neither of them. Please take a look at the documentation for ScheduledThreadPoolExecutor
In particular you are looking at this function
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit unit)
while loop will use CPU resource and it is good only if your avg.waiting time is very less and expecting precision.
Thread.sleep() is fine if no precision is expected as CPU priority will change after thread wakes up and it may or may not be scheduled immediately to run and it also should not to be used like this
while(! canContinue()) {
Thread.sleep(1000);
}
For the above case, alternative is these cases better to use wait()/notify() if you want to suspend the current thread and wait for another thread to process something and then notify the current thread to continue.
some references you can read,
http://tutorials.jenkov.com/java-concurrency/thread-signaling.html
http://www.jsresources.org/faq_performance.html#thread_sleep
I have a client application, where a runnable has to run in a fix period. Therefore I use the java.util.concurrent.ScheduledExecutorService as follows:
ScheduledExecutorService scheduledExecutorService =
Executors.newScheduledThreadPool(10);
ScheduledFuture scheduledFuture =
scheduledExecutorService.scheduleAtFixedRate(runnableClass,
period,period,TimeUnit.SECONDS);
As long as the workload is low, the task is scheduled in the defined period, i.e if the client receives no messages from the server. But if the server shoots out messages at full throttle, the runnableClass.run() is not executed on time. I feel like the time between the execution increases exponentially. But the Computer still runs smooth.
All Exceptions are catched inside run() and if I decrease the messages send from the server, the task is scheduled more often.
Why does that happen?
EDIT: The task needs a lot of resources and it is using Rserve to get predictions computed in R. There are probably up to 5000 calls to R in one task.
I made some tests regarding the time of the task. The task was always done in under a second, while the period was between 3 and 20 seconds.
How many threads are you running and how many cores do you have? Can it happen that you serve every request from a different thread, and the context switchings make your app run slower and slower?
Take care not to have much more CPU-bound threads than cores.
(Just a guess, sorry if it's way off)
Also, do you need a scheduled thread pool executor wit core size of 10? Isn't a SingleThreadScheduledExecutor enough for the scheduled task?
So, I'm trying to create a small game using Swing in Java. The game loop I created uses a javax.swing Timer.
This timer (normally) calls a loop every 5ms.
Timer tm = new Timer(5, this);
tm.start();
#Override
public void actionPerformed(ActionEvent e) {
game.tick();
repaint();
revalidate();
}
My code can be pretty heavy because it contains quite alot of for-loops, so I'm not surprised this isn't actualy running in a loop every 5ms.
Instead, it flows around at a pretty stable 160fps, at least it does on my computer. The moment I tried my game on my brother's computer (less RAM), it at first ran at the same 160fps, but after about 2 minutes the frames drop to a stable 60fps.
I personally find it really weird the frames drop this much at the same time-interval and stays stable like that for the rest of the time.
If anyone encountered a similar problem and knows what is causing it, please let me know. Thanks in advance.
~Krikke
You should use the Timer.scheduleAtFixedRate method instead of the constructor argument.
From the docs (emphasis mine):
In fixed-rate execution, each execution is scheduled relative to the
scheduled execution time of the initial execution. If an execution is
delayed for any reason (such as garbage collection or other background
activity), two or more executions will occur in rapid succession to
"catch up." In the long run, the frequency of execution will be
exactly the reciprocal of the specified period (assuming the system
clock underlying Object.wait(long) is accurate).
As was mentioned in the comments by #HovercraftFullOfEels, you should be making any Swing calls on the Swing Event Thread. For more information, see this tutorial.
So I've had an idea in my head today... And I would like to hear some feed-back. I have a Java app which needs to check a directory every 5 minutes. Plain and simple the app needs to run every five minutes.
Seems like a good candidate for cronjob, but I was wondering... why not keep the logic/timing all within the app like so (simplified obviously):
public static void main(String[] args) {
while(true) { // repeatedly execute...
// do the work/job
Thread.sleep(600 * 1000); // make the thread sleep for 5 minutes
}
}
One significant downside I see is "How do we stop this app once it starts? Deleting it?
Are there any other significant draw-backs to this besides that one?
Should I stop daydreaming and just use cron jobs?
A number of significant drawbacks:
If you ever want to change the polling frequency (i.e. do it every 2 minutes, or every 10 minutes), you have to change the program. This is especially difficult if you have an irregular polling schedule, something like once every 5 minutes on Monday through Friday, but once every 15 minutes on Saturday and Sunday. Sure, you don't think your program will ever need to do that, but requirements evolve.
As you say, killing the process is the only way to stop the program. And killing it in mid-process might be a bad thing. You could of course add some cancel logic, but that's additional development time.
The program is occupying memory while it's sitting there doing nothing (most of the time). This is a waste of resources. Probably not a huge deal when you're working with a system that has many gigabytes of memory, but it becomes an issue when you're working on embedded systems with limited memory.
You're wasting your time writing your own scheduling, which you then have to debug and maintain, when there's already a perfectly good scheduler built into the operating system.
I call this program a "catnap program" because it acts just like a cat: it sleeps most of the time, waking up now and then to stretch and maybe bat a string around for a few minutes, and then goes back to sleep. Programs are not cats.
You can run a task at fixed rate using ScheduledExecutorService and stop it on some action (here by reading System.in):
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
// do some work
}
}, 0, 5, TimeUnit.MINUTES); // every 5 minutes
// when anything is entered, the task is stopped
Scanner sc = new Scanner(System.in);
String whatever = sc.next();
// shutdown the executor
ses.shutdown();
ses.awaitTermination(15, TimeUnit.SECONDS);
}
A solution like the one suggested has the advantage that it will work on an operating system that does not have cron (but every OS will have some kind of scheduler).
On the other hand using cron has these advantages:
The task will be run at the next scheduled time even if it crashes; the solution shown won't run again after a crash until someone restarts it.
Cron will start running the task again after a reboot; the solution proposed doesn't do that.
When the task stops and then shuts down periodically, memory leaks are less critical than in a long-running process.
This list could doubtless be made longer by enumerating more features that have been added to OS level job schedulers over time.
I would use a quartz scheduler within my application. link http://quartz-scheduler.org/
it does control, when you start your application it runs, and when your application stops it will stop. Granted there is more setup, but it's pretty flexiable.