I need to execute some task daily. Can I use ScheduledExecutorService for this? Say a piece of code that is running always at particular interval. My doubt I am keeping CPU busy always running my code, but this code will run my actual task once in a day,week or month depends on configuration.
ScheduledExecutorService schedular = Executors.newScheduledThreadPool(1);
schedular.scheduleAtFixedRate(new MySchedular(), 1, 24, TimeUnit.HOUR);
Or do we have any better option?
For very a basic need you can indeed use a ScheduledExecutorService as you do, but if you want to do complex things like scheduling your task at a given hour in the day, you should consider using quartz-scheduler.
Here is how to schedule a task at 10 PM:
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
JobDetail job = JobBuilder.newJob(MySchedular.class)
.withIdentity("job1", "group1")
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(22, 00))
.build();
// Tell quartz to schedule the job using our trigger
scheduler.scheduleJob(job, trigger);
// and start it off
scheduler.start();
The same trigger created with a cron expression would be:
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger3", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0 22 00 * * ?"))
.build();
Considering that you are using Windows and CronJob is not available, ScheduledExecutorService is a very good choice on your part. The only problem you need to look into is what happens if for whatever reason your process terminates not due to Windows reboot. Usually critical systems have some sort of Watchdog processes that monitor your process and restart it if it was terminated. But this is probably out of scope for this question. In short the answer to your question is: ScheduledExecutorService is the correct choice.
Related
I have a problem. I want to schedule a Task every day at 3:59:30 AM and want to stop the execution at 10:01:00 PM. For the start and end time I use cron expression. (They are not the Problem here). Now I schedule a job as following:
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.start();
JobDetail job = JobBuilder.newJob(Bot.class)
.withIdentity("job", "group")
.build();
Trigger trigger = CronScheduleBuilder.cronSchedule("30 59 3 ? * * *").build();
scheduler.scheduleJob(job, trigger);
No my question is how do I stop the execution of that job at 10:01:00 PM? And does it start automatically at 4PM again?
I have some repeating quartz jobs that use SimpleScheduleBuilder.repeatMinutelyForever(60). Lets say the job initially gets scheduled at 10:02am and runs for 5 minutes completing at 10:07am.
Right now it is getting scheduled to run again at 11:02am but I want it to run again 60 minutes after completing so it should be scheduled at 11:07am instead.
Is there any way to change the scheduling to do this? Or should I use a one time job that creates a new job each time it completes?
Use TriggerListener - see here for some examples in Quartz cookbook.
You will override triggerComplete and in there you will add your rescheduling code:
public void triggerComplete(Trigger trigger, JobExecutionContext context, CompletedExecutionInstruction triggerInstructionCode) {
// check here the triggerInstructionCode value and reschedule your job
super.triggerComplete(trigger, context, triggerInstructionCode);
}
Example for registering a TriggerListener with the scheduler to listen to a specific trigger:
scheduler.getListenerManager().addTriggerListener(myTriggerListener, keyEquals(triggerKey("myTriggerName", "myTriggerGroup")));
See also this answer.
I am working on writing a Job when my application is deployed. This Job should run every 5 mins and it should start immediately. But the problem is it is starting 5 mins after the deployment and repeating for every five minutes. Please help me with the changes required to start it immediately when the application is deployed.
public void contextInitialized(ServletContextEvent servletContextEvent) {
logger.info("contextInitialized() ,Starting instantiating Processor Engine");
try{
JobDetail job = newJob(MyServiceProcessor.class).withIdentity(
"CronQuartzJob", "Group").build();
Trigger trigger = newTrigger().withIdentity("TriggerName", "Group").withSchedule(CronScheduleBuilder.cronSchedule("0 0/5 * * * ?")).build();
scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
}
catch (SchedulerException e) {
logger.error(", contextInitialized() ,Problem in starting Processor Engine"+e);
}
I think in that way you can't start the job immediately. The cron-expression triggers each 0 or 5 minutes.
Alternative you could instantiate the job additionally and execute it manually in the contextInitialized(), if you dont need the JobExecutionContext.
MyServiceProcessor mjob = new MyServiceProcessor();
mjob.execute(null);
Don't use CronTrigger for such simple scheduling. Use SimpleTrigger instead:
Trigger trigger = newTrigger()
.withIdentity("TriggerName", "Group")
.withSchedule(SimpleTriggerBuilder.simpleSchedule()
.withIntervalInMinutes(5)
.repeatForever())
.build();
This will schedule your job to fire right now, and then every 5 minutes.
For more uses of SimpleTrigger you can read Quartz's tutorial on it.
Quartz scheduler wont trigger my job when I start it. My job is scheduled for every hour. but after starting my scheduler, My first job is trigged after an hour. I'm new to quartz. below is my quartz launch code
JobKey feedWSClient = new JobKey("feedWSClient", "feed-validator");
JobDetail feedWSJob = JobBuilder.newJob(this).withIdentity(feedWSClient).build();
Trigger feedWSCListenerTrigger = TriggerBuilder.newTrigger()
.withIdentity("feedWSCListenerTrigger","feed-validator")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0/59 * * * ?")).build();
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.scheduleJob(feedWSJob,feedWSCListenerTrigger);
scheduler.start();
Below code worked for me.
http://quartz-scheduler.org/api/2.2.0/
scheduler.start();
scheduler.triggerJob(feedWSClient);
Need to call the above statement after starting the scheduler with jobkey.
I would like to start a quartz job in five minutes. Be aware that I don't want to start the job EVERY five minutes but only AFTER five minutes.
Currently I'm using the following code but it does not work properly because the quartz job gets executed every 'intervalInMinutes' minutes:
MutableTrigger trigger = (MutableTrigger) TriggerBuilder.newTrigger()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMinutes(intervalInMinutes).withRepeatCount(repeatCount)).build();
return new Rule(trigger);
Thanks for any help
Found answer. I used this code:
trigger = (SimpleTrigger) newTrigger()
.withIdentity("trigger5", "group1")
.startAt(futureDate(5, IntervalUnit.MINUTE)) // use DateBuilder to create a date in the future
.forJob(myJobKey) // identify job with its JobKey
.build();