text: Another Take on Java Scheduling
  Another Take on Java Scheduling
  Join the DZone community and get the full member experience.Join For Free
  Get the Edge with a Professional Java IDE. 30-day free trial..
  Schedule Beans
  With the growing trend for XML configuration I could see the potential for very expressive schedules by creating lots of little schedule beans that could be plugged together. Here’s a very simple example that uses the DailySchedule bean.
  DailySchedule mySchedule = new DailySchedule(); mySchedule.setAt("08:00"); ScheduleContext context = new ScheduleContext(new Date()); for (int i = 0; i < 7; ++i) { ScheduleResult result = mySchedule.nextDue(context); System.out.println("Next due: " + result.getFromDate()); context = context.move(result.getUseNext()); }
  Hopefully you get the gist of how it works. We use the result of one schedule calculation to move the calculation on, and do this in a loop to get through the week. Here’s the output:
  Next due: Thu Mar 29 08:00:00 BST 2012 Next due: Fri Mar 30 08:00:00 BST 2012 Next due: Sat Mar 31 08:00:00 BST 2012 Next due: Sun Apr 01 08:00:00 BST 2012 Next due: Mon Apr 02 08:00:00 BST 2012 Next due: Tue Apr 03 08:00:00 BST 2012 Next due: Wed Apr 04 08:00:00 BST 2012
  From Schedules to Scheduler
  Our schedule can be used with a scheduler of your choice. Here it is with the standard Java Timer.
  public class TimerScheduler { final Timer timer = new Timer(); ScheduleContext context; public TimerScheduler(Date startFrom) { this.context = new ScheduleContext(startFrom); } void schedule(final Runnable job) { DailySchedule schedule = new DailySchedule(); schedule.setAt("08:00"); final ScheduleResult next = schedule.nextDue(context); System.out.println("Scheduled at " + next.getFromDate()); timer.schedule(new TimerTask() { @Override public void run() { job.run(); context = context.move(next.getUseNext()); schedule(job); } }, next.getFromDate()); } }
  Which is started like this.
  TimerScheduler scheduler = new TimerScheduler(new Date()); scheduler.schedule(new Runnable() { @Override public void run() { System.out.println("Hello"); } });
  Here’s the same schedule used with a java.util.concurrent.ScheduledExecutor:
  public class ExecutorScheduler { final ScheduledExecutorService executor = Executors.newScheduledThreadPool(3); ScheduleContext context; public ExecutorScheduler(Date startFrom) { this.context = new ScheduleContext(startFrom); } void schedule(final Runnable job) { DailySchedule schedule = new DailySchedule(); schedule.setAt("08:00"); final ScheduleResult next = schedule.nextDue(context); System.out.println("Scheduled at " + next.getFromDate()); long delay = next.getFromDate().getTime() - System.currentTimeMillis(); executor.schedule(new Runnable() { @Override public void run() { job.run(); context = context.move(next.getUseNext()); schedule(job); } }, delay, TimeUnit.MILLISECONDS); } }
  This can be started in the same way as the Timer example.
  Holidays
  So how does this help with holidays? A BrokenSchedule provides a way of breaking up one schedule with another.
  Here’s our daily schedule wrapped by a WeeklySchedule so it will only run from Monday to Friday.
  DailySchedule dailySchedule = new DailySchedule(); dailySchedule.setAt("08:00"); WeeklySchedule weeklySchedule = new WeeklySchedule(); weeklySchedule.setFrom(DayOfWeek.Days.MONDAY); weeklySchedule.setTo(DayOfWeek.Days.FRIDAY); weeklySchedule.setRefinement(dailySchedule);
  Plugged into our loop from the first example, to display the ‘next due’ dates, we see that it does indeed miss weekends:
  Next due: Wed Apr 04 08:00:00 BST 2012 Next due: Thu Apr 05 08:00:00 BST 2012 Next due: Fri Apr 06 08:00:00 BST 2012 Next due: Mon Apr 09 08:00:00 BST 2012 Next due: Tue Apr 10 08:00:00 BST 2012
  Our holidays are formed by a ScheduleList which is a schedule that is a composite of its child schedules.
  DateSchedule goodFriday = new DateSchedule(); goodFriday.setOn("2012-04-06"); DateSchedule easterMonday = new DateSchedule(); easterMonday.setOn("2012-04-09"); ScheduleList holidayList = new ScheduleList(); holidayList.setSchedules(new Schedule[] { goodFriday, easterMonday });
  We can now use the holidays to break our week day schedule.
  BrokenSchedule brokenSchedule = new BrokenSchedule(); brokenSchedule.setSchedule(weeklySchedule); brokenSchedule.setBreaks(holidayList);
  And now our Easter Weekend looks like this:
  Next due: Wed Apr 04 08:00:00 BST 2012 Next due: Thu Apr 05 08:00:00 BST 2012 Next due: Tue Apr 10 08:00:00 BST 2012 Next due: Wed Apr 11 08:00:00 BST 2012
  Conclusion
  My initial project was called TreeSched because the beans can be seen as specifying a tree of schedules where branches narrow to smaller and smaller intervals of time. The project has since been subsumed into Oddjob, but the API is still quite open and independent and available to anyone who needs schedules but not necessarily a scheduler.
  For more information on Oddjob schedules please see the Oddjob Documentation and if you have any queries on using the API then please post them to the Oddjob Forum.
  Get the Java IDE that understands code & makes developing enjoyable. Level up your code with IntelliJ IDEA. Download the free trial.
  Published at DZone with permission of Rob Gordon , DZone MVB. See the original article here.
  Opinions expressed by DZone contributors are their own.
  {{ parent.title || parent.header.title}}
  {{ parent.tldr }}
  {{ parent.linkDescription }}{{ parent.urlSource.name }}