How the period of #Scheduled cron will be measured? - java

I need to describe how the #Scheduled annotation works.
There are three definition for Scheduled: fixedDelay, fixedRate and cron.
While the period of fixedDelay will be measured from the completion time of each preceding invocation, the period of fixedRate will be measured between the successive start times of each invocation.
But what about the cron period? How he will be measured?
Edit:
I know cron is not a period like the both fixed-information. I will describe my question with an example.
An example-method need 2 minutes to be finished. But with the #Scheduled-Annotation, I will let the method run every minute.
#Scheduled(fixedDelay = 1000)
public void exampleMethod(){}
fixedDelay will wait until the method is completed, and then he wait one minute. So the method will run every 3 Minutes.
#Scheduled(fixedRate = 1000)
public void exampleMethod(){}
fixedRate will wait one minute between the successive start times of each invocation. So the method will run every minute, doesn't matter if the method is completed or not.
#Scheduled(cron = "0 * * * * *")
public void exampleMethod(){}
So I set the cron to run every minute. Will the method be executed every minute or will cron wait until the method is completed?

Cron is a format that describes when a job should run. You can see a lot of good examples here

Cron is not perod, a format similar records indicate periodicity in Linux scheduler Cron.

Related

Java Run Method every 30th second of a minute

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.

Inconsistent job scheduling by job scheduler

I used job scheduler for sending notification at whatever time interval lets say 4 minutes at regular interval so I used
setPeriodic(duration * 60 * 1000); //duration is 4 minutes
but its inconsistent first it sends notification after 1 minute or 2 minute then 1 minute then 4 minutes then 8 minutes also I guess it caches previous duration, its here how I implemented code:
public static void Scheduler(Context context){
ComponentName componentName = new
ComponentName(context, ClsJobService.class);
JobInfo.Builder builder = new JobInfo.Builder(0, componentName)
.setPeriodic(duration * 60 * 1000);
JobScheduler jobScheduler = (JobScheduler)
context.getSystemService (Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(builder.build());
}
You have scheduled a job at the 4-minute interval using JobScheduler on Android L. Once scheduled as periodic, this job can run only once at any time within the interval you set (start: the time you called schedule(), end: plus 4 minutes). And it will only run again after finishing the interval that it has run, only in the new range.... this behavior will continue on until you cancel the job.
e.g: the job was scheduled for 4 minutes as periodic, and 1 minute later it was executed; This job will be run again after 3 minutes, according to the 4 minutes range. In new range, it can execute at any time within 4 min.
If you don't want this periodic behavior from JobScheduler, consider use AlarmManager service to schedule your job to trigger a notification every 4min and reschedule it after triggering the notification.
Obs.: JobScheduler uses the AlarmManager service internally, to schedule a job that need be scheduled, defining the start and end times to run this job.
Android L source code references:
To set times for scheduling a periodic job
To set times for rescheduled the periodic job
When the periodic job is scheduled using AlarmManager
This is working as designed. (and part of the "power" of the JobScheduler)
From the docs:
setPeriodic(): Specify that this job should recur with the provided interval and
flex. The job can execute at any time in a window of flex length at
the end of the period.
Why dont you user Timertask for the same?
https://developer.android.com/reference/java/util/TimerTask.html

quartz if method takes longer then repeat interval start when finish

I have a job that runs every 2 minutes:
org.quartz.CronScheduleBuilder.cronSchedule("0 0/2 * * * ?").withMisfireHandlingInstructionDoNothing()
Currently, if the job takes more than 2 minutes, Quartz waits another 2 minutes to run it again.
How do I start it right away if it took more than the scheduled interval?
I do not want Quartz to create another job and run both concurrently, because in case the job always fails, I don't want to fill the job queue up, I want the job to run with at least a 2 minute interval.
Misfire instructions tell Quartz what to do when a job runs late.
If a job didn't fire on time because the scheduler was down, or because the previous run took longer than expected, or any other cause, that's a misfire. And you can use misfire instructions like withMisfireHandlingInstructionDoNothing() to tell Quartz what to do.
In this case, you're telling Quartz: "If this job takes longer than expected, that is my problem, not yours. Don't fire up another instance concurrently, don't wait for it to finish. Ignore it. Do nothing".
If you want to change this, you can use a different misfire instruction, like withMisfireHandlingInstructionFireAndProceed(), which will instruct Quartz to fire a misfired job as soon as the previous one finishes.
You can look up available misfire instructions for each type of schedule in the API Javadoc.

Running Java scheduler depends on clock time

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 * * * *

Quartz next fire time is still previous trigger time?

I am using Quartz with Spring to schedule jobs. I have a job which has been scheduled to run every hour. The problem is that when the scheduled job takes more than an hour then the job's "next fire time" remains the old time and is not fired (since the fire time is already past).
My question is how can we change "next fire time" if the job takes more time than the scheduled time?
Try using #DisallowConcurrentExecution annotation. With this, you can ensure only one instance of your job would execute at one point of time i.e. (only one instance of jobdetail).
Hence, if your job is taking more time than 1 hour then this annotation will stop the
other instances (i.e other instances will wait until the first running job finishes the execution).
I just guessed ... not sure whether it will work or not.

Categories