使用ScheduledExecutor和Calendar实现复杂任务调度

来源:互联网 发布:java堆栈哪个大 编辑:程序博客网 时间:2024/06/01 07:46
Timer 和 ScheduledExecutor 都仅能提供基于开始时间与重复间隔的任务调度不能胜任更加复杂的调度需求 。比如,设置每星期一的 16:00:10 执行任务。
    该功能使用 Timer 和 ScheduledExecutor 都不能直接实现,但我们可以借助 Calendar 间接实现该功能。

import java.util.Calendar;
import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * <pre>
 *    ScheduledExecutorTest2 Function Description
 *    <p>
 *        @Create Description
 *     <ol>
 *   <li> TODO</li>
 *                ... 
 * </ol>
 *        @Modify Description 
 * <ol>
 *<li> TODO</li>
 *                 ... 
 * </ol>
 *     </p>
 * </pre>
 *  
 * <hr/>
 * Fully qualified name  com.yc.quartz.example.ScheduledExecutorTest2.java
 * <br/>
 * @Author Chris Yu
 * 
 * Create time 下午01:48:08
 * 
 * @version 1.0
 * @since JDK 1.6
 */
public class ScheduledExecutorTest2 extends TimerTask{

private String jobName = "";
/**
 * 方法描述:
 *      <ol>
 *<li>ScheduledExecutorTest2构造函数</li>
 *       </ol>
 * @Author mlzxcs001
 * @CreateDate 2013-6-17 下午01:48:08
 * @param args
 */
public ScheduledExecutorTest2(String jobName) {
this.jobName = jobName;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Date = "+new Date()+", execute " + jobName);
}
}


/**
 * 
 * 方法描述:
 *      <ol>
 *<li> 计算从当前时间currentDate开始,满足条件dayOfWeek,
 * hourOfDay, minuteOfHour, secondOfMinite的最近时间</li>
 *<li></li>
 *<li></li>
 *       </ol>
 * @Author Chris Yu
 * @CreateDate 2013-6-17 下午02:17:52
 * @param currentDate Calendar 对象
 * @param dayOfWeek 每周几
 * @param hourOfDay 每天那几小时段
 * @param minuteOfHour 每小时那几分钟段
 * @param secondOfMinite 每分钟那几秒
 * @return Calendar 对象
 */
public Calendar getEarliestDate(Calendar currentDate, int dayOfWeek,
int hourOfDay, int minuteOfHour, int secondOfMinite) {
//计算当前时间的WEEK_OF_YEAR,DAY_OF_WEEK, HOUR_OF_DAY, MINUTE,SECOND等各个字段值
int currentWeekOfYear = currentDate.get(Calendar.WEEK_OF_YEAR);
int currentDayOfWeek = currentDate.get(Calendar.DAY_OF_WEEK);
int currentHour = currentDate.get(Calendar.HOUR_OF_DAY);
int currentMinute = currentDate.get(Calendar.MINUTE);
int currentSecond = currentDate.get(Calendar.SECOND);
//如果输入条件中的dayOfWeek小于当前日期的dayOfWeek,则WEEK_OF_YEAR需要推迟一周
boolean weekLater = false;
if (dayOfWeek < currentDayOfWeek) {
weekLater = true;
} else if (dayOfWeek == currentDayOfWeek) {
//当输入条件与当前日期的dayOfWeek相等时,如果输入条件中的
//hourOfDay小于当前日期的
//currentHour,则WEEK_OF_YEAR需要推迟一周
if (hourOfDay < currentHour) {
weekLater = true;
} else if (hourOfDay == currentHour) {
                 //当输入条件与当前日期的dayOfWeek, hourOfDay相等时,
                 //如果输入条件中的minuteOfHour小于当前日期的
//currentMinute,则WEEK_OF_YEAR需要推迟一周
if (minuteOfHour < currentMinute) {
weekLater = true;
} else if (minuteOfHour == currentSecond) {
                     //当输入条件与当前日期的dayOfWeek, hourOfDay, 
                     //minuteOfHour相等时,如果输入条件中的
                    //secondOfMinite小于当前日期的currentSecond,
                    //则WEEK_OF_YEAR需要推迟一周
if (secondOfMinite < currentSecond) {
weekLater = true;
}
}
}
}
if (weekLater) {
//设置当前日期中的WEEK_OF_YEAR为当前周推迟一周
currentDate.set(Calendar.WEEK_OF_YEAR, currentWeekOfYear + 1);
}
// 设置当前日期中的DAY_OF_WEEK,HOUR_OF_DAY,MINUTE,SECOND为输入条件中的值。
currentDate.set(Calendar.DAY_OF_WEEK, dayOfWeek);
currentDate.set(Calendar.HOUR_OF_DAY, hourOfDay);
currentDate.set(Calendar.MINUTE, minuteOfHour);
currentDate.set(Calendar.SECOND, secondOfMinite);
return currentDate;
}
public static void main(String[] args) {
ScheduledExecutorTest2 test = new ScheduledExecutorTest2("job1");
//获取当前时间
Calendar currentDate = Calendar.getInstance();
long currentDateLong = currentDate.getTime().getTime();
System.out.println("Current Date = " + currentDate.getTime().toString());
//计算满足条件的最近一次执行时间
Calendar earliestDate = test
.getEarliestDate(currentDate, 2, 16, 0, 10);
long earliestDateLong = earliestDate.getTime().getTime();
System.out.println("Earliest Date = "
+ earliestDate.getTime().toString());
//计算从当前时间到最近一次执行时间的时间间隔
long delay = earliestDateLong - currentDateLong;
//计算执行周期为一星期
long period = 7 * 24 * 60 * 60 * 1000;
ScheduledExecutorService service = Executors.newScheduledThreadPool(10);
//从现在开始delay毫秒之后,每隔一星期执行一次job1
service.scheduleAtFixedRate(test, delay, period,TimeUnit.MILLISECONDS);
}

}

执行结果为:
Current Date = Mon Jun 17 15:51:59 CST 2013
Earliest Date = Mon Jun 17 16:00:10 CST 2013
Date = Mon Jun 17 16:00:10 CST 2013, execute job1
0 0