For example, I have a task which should be executed between 8:00-20:00 every minites every day.
so i calculate the time gap between 8:00 and the time which my app started for initialDelay, and use Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(command, initialDelay, 1, TimeUnit.MINUTE).
The question is, do I need the second timer to observe the task and cancel it when the clock comes to 20:00? or do I have to compare if the time is 20:00 at every time when the task's executed?
You probably need a real scheduler.
See Quartz https://quartz-scheduler.org
It should fit your needs
For the cron syntax : http://quartz-scheduler.org/api/2.2.0/org/quartz/CronTrigger.html
Or with a fluent API http://quartz-scheduler.org/api/2.2.0/org/quartz/TriggerBuilder.html
Related
I have the following while loop:
while (keepRunning) {
if (!once) {
// Run a test method every 30th second
// Run the new calculations from the database
new CalculatorDriver().run();
// Wait in the while loop for 1 second before looping again
TimeUnit.SECONDS.sleep(1);
}
}
This while loop will loop every second through the code, but now I want to run a method called: getNewCalculations() every 30th second of a minute, so for example, the method needs to run at:
18:26:30
18:27:30
18:28:30
I already found a way to run a method every x seconds:
Timer timer = new Timer();
timer.schedule(new Task(), 60 * 1000);
But I also need to start it at a specific point. In C# someone tried this to run a script every 30th and every 0th second: https://stackoverflow.com/a/53846390/10673107.
I could just add an if where the second can't be equal to 0, but I was wondering if there was a better way to do this.
How can I run it only in the 30th second?
Set an initial delay by calculating the number of seconds to wait until the next 30th second is due to arrive. If the current moment is :10, wait 20 seconds. If the current moment is :56, wait 34 seconds.
The Duration class may help with that, along with ZonedDateTime class.
If you read the Javadoc for Timer/TimerTask you will learn those classes were supplanted years ago by the Executors framework that arrived in Java 5.
Use a ScheduledExecutorService to schedule a task to run after an initial delay specified by you. After the initial delay, specify a repeating period of one minute.
Your task will then be repeating on the 30th second mark of every minute. Know that this scheduling is approximate. The host OS, the JVM’s internal scheduler, and garbage-collection all impact when the task actually runs. So each run may vary.
Or, if you want to protect against any politician-imposed anomalies on your region’s time-keeping, schedule only a one-time scheduled task rather than repeating task. Pass to that task a reference to the ScheduledExecutorService object. The task can then schedule its own next run after running the initial-delay calculation again.
Be sure to eventually shutdown your executor service. Otherwise its backing pool of threads may continue to run indefinitely even after your app ends, like a zombie 🧟♂️.
Be aware that any exception or error bubbling up to the scheduled executor service will silently halt any further scheduling.
All of these topics have been addressed many times already on Stack Overflow. Search to learn more.
I have a particular requirement on scheduler. I need to run a scheduler after every 30 minutes. This can be done easily but the problem is this scheduler is depends on clock time. Like suppose I have start my program at 00:15 then with start my scheduler will not start. First scheduler will run at 00:30 and from then it will run with 30 minutes interval.
Need help on the same. I am using Java 8.
Timer and TimerTask classes can be used.
Timer class contains a method schedule() in that you can pass your task(TimerTask).
Sigtnature of the method as follows :
public void schedule(TimerTask task,long delay,long period)
First parameter : TimerTask object
Second paramter : delay in millisecond, after the mentioned milliseconds task will start to execute.
Third parameter: period in millicond, subsequent executions will happen at regular intervals of mentioned period of time.
Refer to : https://docs.oracle.com/javase/8/docs/api/java/util/Timer.html
What you looking for is called cron sceduling it can give you the ability to run your job for example every Monday at 10 am or every 30 minute of every hour
here are some links
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html
How to create a Java cron job
https://www.mkyong.com/java/java-cron-job-to-run-a-jar-file/
This requirement is called crn job. The below cron settings needed to achieve the above requirement.
*/30 * * * *
I have started timer with fixed rate. When user change system Time at that time task is executed continuously.It doesn't consider about the period time. How to manage this.
timer.scheduleAtFixedRate(task, delay, period);
Note : Now system time is current time.Period is 30 seconds. Now user change system time into after 10 mins from current time.At that time timer task not consider about the period. Within a second it execute the task 20 times.
When I use
timer.schedule(task, delay, period);
instead of
timer.scheduleAtFixedRate(task, delay, period);
task working normally. If I change system time to 10 mins past time from now task doesn't executed...
How to solve this ? :(
Have a look at this Stack Overflow answer; long story short, using scheduleAtFixedRate will queue up the tasks you have scheduled and fire them relative to the system time that the task was first queued; if anything should delay these tasks from firing, they will play 'catch up' and fire as fast as they can. So in your example of how changing the system time to +10 minutes made the event fire 20 times make since given that your period is 30 seconds (1m/2 = 30s, 10m*2 = 20 events).
Using the schedule function has similar issues, except it does not play 'catch up'; if you had a timer set to fire off every 30 seconds, then change the system time to +10 minutes only 10 seconds after the timer has started, your first event will trigger, then continue to wait the 30 second delay and fire again (unless you change the system clock again).
If you want something that is independent of system time you'll need monotonic clock values. To my knowledge the Java API does not directly contain any monotonic timers (for numerous reasons), but that doesn't stop you from implementing one yourself (albeit at the cost of possible wasted execution time in custom timer class code). Here's a Stack Overflow question regarding this, as well as a Google Group discussion post on it.
If you're really hard pressed for using a monotonic timer you could potentially use the POSIX API's and do some Java->C JNI work.
I hope that can help (at least point in a solid direction).
Is it possible to schedule multiple TimerTasks such that they all begin at the same time and if so how would I do it? In particular I would like to initiate these tasks at the same exact time so that the relative time difference between each task is as specified (I want to be as accurate as possible).
toneIntervalClock.scheduleAtFixedRate(tonePlayerTask, 250, 5000);
startRecordingClock.scheduleAtFixedRate(startRecordingTask,0,5000);
stopRecordingClock.scheduleAtFixedRate(stopRecordingTask, 1000, 5000);
Also would it be better practice to use the same Util Timer to schedule each task?
Thanks
The system will try to make scheduleAtFixedRate tasks fire with low jitter, but you don't ever get any guarantees with concurrency.
Your approach of trying to initialize all of the tasks and then run them is a decent one. The only suggestion I would make is to use Timer#scheduleAtFixedRate(TimerTask task, Date firstTime, long period), since then you don't have any jitter in between your schedule calls and can start them all from a fixed time reference.
I want to write a simple timer class that fires , and makes a method call at a fixed time of every day, while the application is running.
I dont want to use Quartz as I think its a overkill for this simple problem, what are the different approaches I can try for ?
Thanks in Advance
Why not use java.util.Timer and java.util.TimerTask?
The util.concurrent's ScheduledExecutorService allows you to pretty easily schedule tasks to run on a fixed delay. The signature of the schedule method is as follows:
scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
You could find the difference between the current time and the time in which you wish to have it first run. Set the difference as the value for initialDelay. Set the period to 1 and the TimeUnit unit to TimeUnit.DAYS. That will cause it to run every day at that time.