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.
Related
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?
I am writing a game in Java. I have in-game tutorials. Each tutorial is essentially a 5-10 frame animation that changes every second.
For each tutorial, I have a simple thread running:
int sleepTimeMillis = 1000;
public static void run() {
while ( true ) {
try {
tutorialFrame = ( tutorialFrame + 1 ) % numberOfFrames;
Thread.sleep ( sleepTimeMillis );
catch ( InterruptedException e ) {}
}
}
I currently have about 10 of these running. By the time I finish all of them, I imagine I'll have about 50.
Otherwise, my game uses a handful of threads: One for the windowing environment, one for the game logic, one for the rendering engine, and probably a handful of other small ones here and there.
Unsurprisingly, I haven't noticed any speed issues in the game by adding these threads. That being said, I'm not knowledgeable on the behind-the-scenes overhead for having many threads within a process.
I could restructure the program in a different way if it is desirable to reduce the number of these tutorial threads.
So I'm asking whether it's worth the time to re-structure the tutorials a little so they all share one thread, or whether it makes sense to just leave things how they are.
Thanks!
Threads are tricky. The first time people learn threads concept, they think: "Awesome, now I can run everything in parallel! I will use threads as much as possible everywhere!". But there are pitfalls. Let's start from the CPU, that has multiple cores. To a first approximation, the number of threads which can be run simultaneously is equal to the number of cores (detailed comments on that, like hyperthreading, are welcome). So, if you created 100 threads, only 4 can be executed simultaneously on a machine with 4 cores. And there is a thread scheduler, which schedules threads for execution.
The process when thread scheduler gives CPU time from one thread to another is called context switch and it takes some time. Moreover, when you create a new thread you allocate some memory for its stack. Considering that, having many (let's say 50) threads is bad because:
you are using extra memory. On a x64 machine default thread stack size is 1MB. 50 threads = 50 MB.
context switch happens too frequently, you are loosing time on that.
You'll end up with having many threads, that most of the time do nothing, just wasting resources. So, what's the solution? Instead of creating new threads each time you need to execute some task asynchronously, you can use ExecutorService, there is a nice article on that. Also, looking at your code, it looks like you are executing recurrent task. If so, you can use Timer class, just create TimerTask and schedule it at fixed rate.
It is more efficient to have your tutorial as sprites and use the Sprites Update and draw methods. That way you are only using the one thread to update everything. Having more then one thread do the work is a waste.
I have a scenario of running 2 separate standalone java polling tool where it would run some specific task with a fixed interval of 5 minutes.
MY scenario is (for each polling service):
1) if a task T0 is required more than 5 minutes to run and meanwhile after 5 minutes T5 comes and tries to execute , i would discard it, not wait,or relaunch (Discard overlapping tasks)
2) The next task would start at T10 normally.
My question is is using Quartz will be an overkill ? I f I use TaskExecutorService how can I check on time X that once task started on time X-5 is already running and I should discard it.
Note:
1) I must use JDK <= 6.0
2) I am not using under any framework like spring.
3) its an desktop tool so I need to launch it and it would run..
Any code snippet or direction is appreciated.
UPDATED for the answer of the comment below:
Yes its between tasks running in a single tool. The tools are different, there is no connection between the tools,they will run separately and has no relation.
a single tool runs a same task in a 5 minutes interval (like every file minute it looks inside a directory for files and if found parses those files and works with them).
If ,say for an example once the task is currently running started from first minute (it may take any amount of time), after 5 minutes the tool launches that task again looking for new files, but this time it will not parse/work with it, as a previous task is already running processing some files.so the new task will not execute and the system will dump it(NO queue/ no waiting / no sequential jobs ).
Another new task will again run on 5x time and if no other is running it will parse and process those files.
After seeing the reply on the question in the comment, you can use Excecutors to obtain a ScheduledExecutorService. Then, you can use the method scheduleWithFixedDelay to submit your task. This method reruns the task with a delay between the runs. The good thing for your case is that the delay counting starts after the current run finishes. This will give you what you want without using a boolean variable or a ReentrantLock as you will not have two tasks running at the same time. You just need to be careful to catch exceptions as an exception will cause subsequent runs of the task to be cancelled.
So lets assume you have a class MyTask which implements runnable
public class MyTask implements Runnable{
public void run() {
try {
//your task code here
} catch (...) {
//deal with the exceptions here
}
}
}
assuming you will run from main method, you can now use the class to schedule the reoccurring task:
public class TaskRunner{
private static final ScheduledExecutorService taskScheduler = Executors.newScheduledThreadPool(1);
public static void main(String[] args) {
taskScheduler.scheduleWithFixedDelay(new MyTask(),0,5,TimeUnit.MINUTES);
}
}
The solution is simple: use ScheduledThreadPoolExecutor.scheduleAtFixedRate(task, 5, min). Declare a common boolean variable isRunning=false. Each task checks this variable at the start, and if it is set already, exits, otherwise sets it to true and runs. At the end, sets it to false. Checking and setting should be done in a synchronized block.
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.
Is tight looping in a program bad?
I have an application that has two threads for a game-physics simulator. An updateGame thread and a render thread. The render thread is throttled by causing the thread to sleep for some milliseconds (to achieve the frame-rate I want) and the updateGame thread (that updates my in game objects positions based off some physics equations) was previously throttled by a 10 millisecond sleep.
However, I recently unthrottled the updateGame thread and the simulation of my objects movement seems to be significantly more realistic now that I have taken out that 10ms sleep. Is it bad to hot loop or have a tight loop?
private class UpdateTask implements Runnable
{
private long previousTime = System.currentTimeMillis();
private long currentTime = previousTime;
private long elapsedTime;
public void run()
{
while(true)
{
currentTime = System.currentTimeMillis();
elapsedTime = (currentTime - previousTime); // elapsed time in seconds
updateGame(elapsedTime / 1000f);
try {
Thread.currentThread().sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
previousTime = currentTime;
}
}
}
In this example I'm just sleeping for 1ms (and from my understanding with how millisecond accuracy and the sleep function works this is probably more like 5-10ms. If I sleep for any more than this it starts to have impacts on the accuracy of my collision detection and physics model.
Is it a bad practice to have tight loops or loops with 1ms sleeps in them? Is there something else I should do instead?
I read a really great post about efficiently and effectively executing physics calculations loop: Fix Your Timestep!
When a game is running that is usually the main application that the user cares about so tight looping is not that big of a deal. What you really should do though schedule your updates. You should know how long -- at your target framerate -- that your frame has to execute. You should measure the time that your frame took and only sleep for the time that your frame took minus that known frame time. That way your system will lock into a frame rate and not vary with the amount of time that your frame takes to render.
Another thing is that I don't believe that Thread.sleep has a very good resolution, well over 5 milliseconds, you may want to look for a more accurate timer available for Java.
It's only "bad" if it has an adverse impact on something else in your system. Rather than sleeping for 1ms, you might block on a condition that warrants updating, with a minimum of 1ms. That way you'll always sleep for at least 1ms, and longer if there's nothing to do.
As Adam has pointed out in his answer, there may be an adverse impact on the performance of the system.
I've also tried making games in a very similar manner (having a rendering and motion calculations on separate threads) and I have found that not having the Thread.sleep will cause the Java application to take a very significant portion of the CPU time.
Another thing to consider is that the system timer itself. As you've mentioned, although the Thread.sleep method is takes in the number of milliseconds to sleep, but that precision is dependent (as noted in the API specifications) on the timer provided by the operating system. In the case of Windows NT-based operating systems, the timer resolution is 10 milliseconds. (See also: System.currentTimeMillis vs System.nanoTime)
Yes, it is true that having the Thread.sleep has the potential to decrease the performance of your application, but not having that can cause the system utilization by the application to skyrocket.
I would guess the decision comes down to whether the application should take up a significant portion of the system utilization, or to act nice and share the CPU time with the other applications running on the system.
Also consider laptop users, running a tight loop continuously will keep the CPU running hard, and this will chew through their battery (many flash games are guilty of this). Something to consider when deciding whether to throttle your loops or not.
The answer by joshperry is pretty much what you want, but there are also a few ways about it. If you are using multiple threads, you have to also deal with locking etc. Depending on your game architecture that may / may not be a big deal. For example, do you do lots of locking, is there a lot of message passing between threads etc. If you are a traditional game you usually have a single main loop - I have a queue of CMD objects (runnable if you like, but can also be more event bus like in nature) that are executed continuously until the queue is empty. The thread then waits until it is signaled that a new cmd is in the queue. For most games this is usually enough. So the question then becomes how / when are cmds added. I use a timer/scheduler (also note the comments about java time resolution) to add a cmd to the main loop at the required frame rate. This has the advantage of also being kind to laptops etc. On startup you can also then benchmark the system to see how fast it is running, and then set an appropriate frame rate (ie. start with a supported base, then work to a max). Benchmarking or using user specified performance hints (ie. amount of rendering detail) can then be used by each type of cmd (ie. the render scence cmd / event looks at the performance settings for detail etc). (note - cmds dont' have to be runnable, they can be more like an event bus with listeners that are invoked on the main thread).
Also if a task wants to then use multi-thread/core's the handler for the cmd (if its an event type model - i personally like the event model - its easier to access the shared state info without needing global singletons) can then spawn multiple tasks (say using an existing thread pool - so the cost of new threads are not hit every cmd) and then use a barrier type class to wait for all the tasks to complete. This method usually makes locking easier, as each cmd (or system) usually has different locking requirements. Thus you can implement just the locking for that system and not have to worry about locking between sub systems - ie. for physics you can lock on bundles of objects in the game area, and each forked thread in the thread pool then worries only about its objects ie. thread1 handles objects1 to 20, thread2 objects 21-40 etc (this is just to illustrate the concept of how each cmd can implement a custom locking algorithm that works best for what it is doing, without having to worry about what other sub systems are doing with shared state data).
The important thing is to look at how and why you are using threads and locking etc.
For a game, probably not. Just make sure your game pauses when the switches tasks.
You would actually want to use Thread.yield() in this case. It is possible that one thread will run continuously, and not allow any other threads time to execute. Placing a yield call at the end of each iteration gives the scheduler a hint that it is time to allow other threads to run as well.