几种任务调度的 Java 实现方法与比较
- wangyegang - IBM developerWorks 中国 : 文档库综观目前的 Web 应用,多数应用都具备任务调度的功能. 本文由浅入深介绍了几种任务调度的 Java 实现方法,包括 Timer,Scheduler, Quartz 以及 JCron
Tab,并对其优缺点进行比较,目的在于给需要开发任务调度的程序员提供有价值的参考.
package com.ljn.timer; import java.util.Date; import java.util.Timer; /** * @author lijinnan * @date:2013-11-25 下午3:27:43 */ public class TimerException { public static void main(String[] args) { System.out.println("start:" + new Date()); Timer timer = new Timer(); int delay = 1000; int period = 2000; timer.schedule(new OKTask(), delay * 2, period); //"OKTask" does not get chance to execute timer.schedule(new ErrorTask(), delay, period); //exception in "ErrorTask" will terminate the Timer } /*输出: start:Mon Nov 25 17:49:53 CST 2013 ErrorTask is executing... error:Mon Nov 25 17:49:55 CST 2013 Exception in thread "Timer-0" java.lang.RuntimeException: something wrong at com.ljn.timer.ErrorTask.run(ErrorTask.java:14) */ }
package com.ljn.timer; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * @author lijinnan * @date:2013-11-25 下午3:35:39 */ public class ScheduledExecutorServiceTest { public static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2); public static void main(String[] args){ System.out.println("start:" + new Date()); ErrorTask errorTask = new ErrorTask(); OKTask okTask = new OKTask(); int delay = 1000; int period = 2000; scheduledExecutorService.scheduleAtFixedRate(errorTask, delay, period, TimeUnit.MILLISECONDS); //"ErrorTask" throws Exception and then stopes. scheduledExecutorService.scheduleAtFixedRate(okTask, delay * 2, period, TimeUnit.MILLISECONDS); //"OKTask" is executed periodically, not affected by "ErrorTask" //scheduledExecutorService.shutdown(); } /* start:Mon Nov 25 17:54:22 CST 2013 ErrorTask is executing... error occurs:Mon Nov 25 17:54:24 CST 2013 OKTask is executed:Mon Nov 25 17:54:24 CST 2013 OKTask is executed:Mon Nov 25 17:54:26 CST 2013 OKTask is executed:Mon Nov 25 17:54:28 CST 2013 ...... */ }
package com.ljn.timer; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * @author lijinnan * @date:2013-11-25 下午5:18:55 */ public class FixedDatetimeTaskTest { public static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1); public static void main(String[] args) throws Exception { System.out.println("start:" + new Date()); //每天的02:30:00执行任务 long delay = Helper.calcDelay(2, 30, 0); long period = Helper.ONE_DAY; scheduledExecutorService.scheduleAtFixedRate(new OKTask(), delay, period, TimeUnit.MILLISECONDS); } }
package com.ljn.timer; import java.util.Date; import java.util.TimerTask; public class ErrorTask extends TimerTask { @Override public void run() { try { System.out.println("ErrorTask is executing..."); Thread.sleep(1000); System.out.println("error occurs:" + new Date()); throw new RuntimeException("something wrong"); } catch (InterruptedException e) { } } }
package com.ljn.timer; import java.util.Date; import java.util.TimerTask; public class OKTask extends TimerTask { @Override public void run() { System.out.println("OKTask is executed:" + new Date()); } }
package com.ljn.timer; import org.joda.time.DateTime; /** * @author lijinnan * @date:2013-11-25 下午5:17:40 */ public class Helper { private Helper() {} public static final long ONE_DAY = 60 * 60 * 24; public static long calcDelay(int hour, int minute, int second) { if (!(0 <= hour && hour <=23 && 0 <= minute && minute <=59 && 0 <=second && second <= 59)) { throw new IllegalArgumentException(); } return calcDelay(fixed(hour, minute, second)); } private static long calcDelay(DateTime targetDatetimeOfToday) { long delay = 0; DateTime now = new DateTime(); //时间点已过,只好延时到明天的这个时间点再执行 if (now.isAfter(targetDatetimeOfToday)) { delay = now.plusDays(1).getMillis() - now.getMillis(); //时间点未到 } else { delay = targetDatetimeOfToday.getMillis() - now.getMillis(); } return delay; } /** * 返回这样一个DateTime对象: * 1.日期为今天 * 2.时分秒为参数指定的值 * @param hour 0-23 * @param minute 0-59 * @param second 0-59 * @return */ private static DateTime fixed(int hour, int minute, int second) { return new DateTime() .withHourOfDay(hour).withMinuteOfHour(minute).withSecondOfMinute(second); } }