`
javacoo
  • 浏览: 65626 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

简易而不简单的定时任务框架

阅读更多
今天在网上发现了这个定时任务框架,绝对的好东西啊,废话不多直接上代码了。
整个框架就3个类:
ScheduleIterator.java

import java.util.Date;

public interface ScheduleIterator {
Date next();
}


Scheduler.java

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class Scheduler {
class SchedulerTimerTask extends TimerTask {
private SchedulerTask schedulerTask;
private ScheduleIterator iterator;

public SchedulerTimerTask(SchedulerTask schedulerTask,
ScheduleIterator iterator) {
this.schedulerTask = schedulerTask;
this.iterator = iterator;
}

public void run() {
schedulerTask.run();
reschedule(schedulerTask, iterator);
}
}

private final Timer timer = new Timer();

public Scheduler() {
}

public void cancel() {
timer.cancel();
}

public void schedule(SchedulerTask schedulerTask, ScheduleIterator iterator) {

Date time = iterator.next();
if (time == null) {
schedulerTask.cancel();
} else {
synchronized (schedulerTask.lock) {
if (schedulerTask.state != SchedulerTask.VIRGIN) {
throw new IllegalStateException("Task already scheduled or cancelled");
}
schedulerTask.state = SchedulerTask.SCHEDULED;
schedulerTask.timerTask = new SchedulerTimerTask(schedulerTask,
iterator);
timer.schedule(schedulerTask.timerTask, time);
}
}
}

private void reschedule(SchedulerTask schedulerTask,
ScheduleIterator iterator) {

Date time = iterator.next();
if (time == null) {
schedulerTask.cancel();
} else {
synchronized (schedulerTask.lock) {
if (schedulerTask.state != SchedulerTask.CANCELLED) {
schedulerTask.timerTask = new SchedulerTimerTask(
schedulerTask, iterator);
timer.schedule(schedulerTask.timerTask, time);
}
}
}
}

}

SchedulerTask.java

import java.util.TimerTask;

public abstract class SchedulerTask implements Runnable {
final Object lock = new Object();

int state = VIRGIN;
static final int VIRGIN = 0;
static final int SCHEDULED = 1;
static final int CANCELLED = 2;

TimerTask timerTask;

protected SchedulerTask() {
}

public abstract void run();

public boolean cancel() {
synchronized (lock) {
if (timerTask != null) {
timerTask.cancel();
}
boolean result = (state == SCHEDULED);
state = CANCELLED;
return result;
}
}

public long scheduledExecutionTime() {
synchronized (lock) {
return timerTask == null ? 0 : timerTask.scheduledExecutionTime();
}
}

}
========================================================================================================
以下是我自己写的一个 ScheduleIterator  实现类 以及一个测试类
SimpleScheduleIterator.java

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import com.jeecms.common.task.scheduling.ScheduleIterator;
/**
* 时间进度迭代器
* <li>返回 月/周/天/小时/分钟/秒 计划的下一次执行时间</li>
* <li>约定:参数以逗号分隔,*号表示无值</li>
* <li>参数解释:
* <br>第一位:每个月的第几周</br>
* <br>第二位:每周的第几天</br>
* <br>第三位:天(几号)</br>
* <br>第四位:小时(24小时制)</br>
* <br>第五位:分钟</br>
* <br>第六位:秒</br>
* </li>
* <li>参数样例:
*  <br> 1,6,4,15,20,30       表示 从今天的15:20:30开始,每隔一个月执行一次,即下次执行时间是  下个月的第一周的第6天的15:20:30</br>
*  <br> *,6,4,15,20,30       表示 从今天的15:20:30开始,每隔一周执行一次,即下次执行时间是  下一周的第6天的15:20:30</br>
*  <br> *,*,4,15,20,30       表示 从今天的15:20:30开始,每隔一天执行一次,即下次执行时间是  下一天的15:20:30</br>
*  <br> *,*,*,15,20,30       表示 从今天的15:20:30开始,每隔一小时执行一次,即下次执行时间是  16:20:30</br>
*  <br> *,*,*,*,20,30        表示 从这个小时的20:30开始,每隔一分钟执行一次,即下次执行时间是  *:21:30</br>
*  <br> *,*,*,*,*,30         表示 从当前时间的30秒开始,每隔一秒执行一次,即下次执行时间是  *:*:31</br>
* </li>
* @author javacoo
* @since 2011-11-03
*/
public class SimpleScheduleIterator implements ScheduleIterator {
private final ScheduleParamBean scheduleParamBean;
private final Calendar calendar = Calendar.getInstance();
private final Calendar orginCalendar = Calendar.getInstance();
public SimpleScheduleIterator(final ScheduleParamBean scheduleParamBean) {
this(scheduleParamBean, new Date());
}

public SimpleScheduleIterator(final ScheduleParamBean scheduleParamBean, Date date) {
this.scheduleParamBean = scheduleParamBean;

orginCalendar.setTime(date);
calendar.setTime(date);
if(null != scheduleParamBean.getWeekOfMonth()){
calendar.set(Calendar.WEEK_OF_MONTH, scheduleParamBean.getWeekOfMonth());
}
//如果设置了每周的第几天和一个月的第几天,则忽略一个月的第几天
if(null != scheduleParamBean.getDayOfWeek()){
calendar.set(Calendar.DAY_OF_WEEK, scheduleParamBean.getDayOfWeek());
}else if(null != scheduleParamBean.getDayOfMonth()){
calendar.set(Calendar.DAY_OF_MONTH, scheduleParamBean.getDayOfMonth());
}
if(null != scheduleParamBean.getHourOfDay()){
calendar.set(Calendar.HOUR_OF_DAY, scheduleParamBean.getHourOfDay());
}
if(null != scheduleParamBean.getMinute()){
calendar.set(Calendar.MINUTE, scheduleParamBean.getMinute());
}
if(null != scheduleParamBean.getSecond()){
calendar.set(Calendar.SECOND, scheduleParamBean.getSecond());
}
calendar.set(Calendar.MILLISECOND, 0);

if (!calendar.getTime().before(date)) {
System.out.println(calendar.getTime() +"大于当前时间:"+date);
if(null != scheduleParamBean.getWeekOfMonth()){
calendar.add(Calendar.MONTH, -1);
}else if(null != scheduleParamBean.getDayOfWeek()){
calendar.add(Calendar.DAY_OF_WEEK, -6);
}else if(null != scheduleParamBean.getDayOfMonth()){
calendar.add(Calendar.DAY_OF_MONTH, -1);
}else if(null != scheduleParamBean.getHourOfDay()){
calendar.add(Calendar.HOUR_OF_DAY, -1);
}else if(null != scheduleParamBean.getMinute()){
calendar.add(Calendar.MINUTE, -1);
}else if(null != scheduleParamBean.getSecond()){
calendar.add(Calendar.SECOND, -1);
}
}else{
System.out.println(calendar.getTime() +"小于当前时间:"+date);
if(null != scheduleParamBean.getDayOfMonth()){
calendar.add(Calendar.DAY_OF_MONTH, orginCalendar.get(Calendar.DAY_OF_MONTH) - scheduleParamBean.getDayOfMonth());
}else if(null != scheduleParamBean.getHourOfDay()){
calendar.add(Calendar.HOUR_OF_DAY, orginCalendar.get(Calendar.HOUR_OF_DAY) - scheduleParamBean.getHourOfDay());
}else if(null != scheduleParamBean.getMinute()){
calendar.add(Calendar.MINUTE, orginCalendar.get(Calendar.MINUTE) - scheduleParamBean.getMinute());
}else if(null != scheduleParamBean.getSecond()){
calendar.add(Calendar.SECOND, orginCalendar.get(Calendar.SECOND) - scheduleParamBean.getSecond());
}
}
}

public Date next() {
if(null != scheduleParamBean.getWeekOfMonth()){
calendar.add(Calendar.MONTH, 1);
}else if(null != scheduleParamBean.getDayOfWeek()){
calendar.add(Calendar.DAY_OF_WEEK, 6);
}else if(null != scheduleParamBean.getDayOfMonth()){
calendar.add(Calendar.DAY_OF_MONTH, 1);
}else if(null != scheduleParamBean.getHourOfDay()){
calendar.add(Calendar.HOUR_OF_DAY, 1);
}else if(null != scheduleParamBean.getMinute()){
calendar.add(Calendar.MINUTE, 1);
}else if(null != scheduleParamBean.getSecond()){
calendar.add(Calendar.SECOND, 1);
}
System.out.println("下次执行时间:"+calendar.getTime());
return calendar.getTime();
}


}
ScheduleParamBean.java
/**
* 时间计划参数bean
* @author javacoo
* @since 2011-11-04
*/
public class ScheduleParamBean {
/**每个月的第几周,每周的第几天,每个月的第几天,小时(24小时制),分钟,秒*/
private Integer weekOfMonth,dayOfWeek,dayOfMonth,hourOfDay, minute, second;

public ScheduleParamBean(){

}

public ScheduleParamBean(Integer weekOfMonth, Integer dayOfWeek,
Integer dayOfMonth, Integer hourOfDay, Integer minute,
Integer second) {
super();
this.weekOfMonth = weekOfMonth;
this.dayOfWeek = dayOfWeek;
this.dayOfMonth = dayOfMonth;
this.hourOfDay = hourOfDay;
this.minute = minute;
this.second = second;
}

public Integer getWeekOfMonth() {
return weekOfMonth;
}

public void setWeekOfMonth(Integer weekOfMonth) {
this.weekOfMonth = weekOfMonth;
}

public Integer getDayOfWeek() {
return dayOfWeek;
}

public void setDayOfWeek(Integer dayOfWeek) {
this.dayOfWeek = dayOfWeek;
}

public Integer getDayOfMonth() {
return dayOfMonth;
}

public void setDayOfMonth(Integer dayOfMonth) {
this.dayOfMonth = dayOfMonth;
}

public Integer getHourOfDay() {
return hourOfDay;
}

public void setHourOfDay(Integer hourOfDay) {
this.hourOfDay = hourOfDay;
}

public Integer getMinute() {
return minute;
}

public void setMinute(Integer minute) {
this.minute = minute;
}

public Integer getSecond() {
return second;
}

public void setSecond(Integer second) {
this.second = second;
}

@Override
public String toString() {
return "ScheduleParamBean [dayOfMonth=" + dayOfMonth + ", dayOfWeek="
+ dayOfWeek + ", hourOfDay=" + hourOfDay + ", minute=" + minute
+ ", second=" + second + ", weekOfMonth=" + weekOfMonth + "]";
}




}



TestSchedule.java

/**
* 测试
* @author javacoo
* @since 2011-11-03
*/
public class TestSchedule {
private final Scheduler scheduler = new Scheduler();

private final ScheduleParamBean scheduleParamBean;

public TestSchedule(final ScheduleParamBean scheduleParamBean) {
this.scheduleParamBean = scheduleParamBean;
}

public void start() {
scheduler.schedule(new SchedulerTask() {
public void run() {
execute();
}
private void execute() {
System.out.println("任务执行");
}
}, new SimpleScheduleIterator(scheduleParamBean));
}

public static void main(String[] args) {

ScheduleParamBean scheduleParamBean = new ScheduleParamBean();
//scheduleParamBean.setWeekOfMonth(1);
scheduleParamBean.setDayOfWeek(4);
scheduleParamBean.setDayOfMonth(4);
scheduleParamBean.setHourOfDay(22);
scheduleParamBean.setMinute(59);
scheduleParamBean.setSecond(0);
TestSchedule test = new TestSchedule(scheduleParamBean);
test.start();

}

}
=====================================================================================================

以下是整合到JEECMS采集器多线程版的代码片段


/**
* 开始执行采集任务
*/
public boolean start(Integer id) {
CmsAcquisition acqu = cmsAcquisitionMng.findById(id);
if (acqu == null || acqu.getStatus() == CmsAcquisition.START) {
return false;
}
TaskSchedulerManage taskManage = new TaskSchedulerManage(this,acqu);
taskManage.start();
return true;
}


private class TaskSchedulerManage {
private final Scheduler scheduler = new Scheduler();
private final MultiThreadAcquisitionSvcImpl multiThreadAcquisitionSvc;
private final CmsAcquisition acqu;
public TaskSchedulerManage(MultiThreadAcquisitionSvcImpl multiThreadAcquisitionSvc,CmsAcquisition acqu) {
this.multiThreadAcquisitionSvc = multiThreadAcquisitionSvc;
this.acqu = acqu;
}
public void start() {
scheduler.schedule(new SchedulerTask() {
public void run() {
processer();
}
private void processer() {
System.out.println("============开始执行计划任务=================");
new Thread(new MainThreadProcesser(multiThreadAcquisitionSvc,acqu)).start();
}
}, new SimpleScheduleIterator(new ScheduleParamBean(1,6,4,17,24,30)));
}
}

很简单吧!!关键是 ScheduleIterator实现类了,框架有多强大 完全取决于你的ScheduleIterator实现类了。
分享到:
评论

相关推荐

    C#自制简易任务管理器

    在本项目中,"C#自制简易任务管理器" 是一个使用C#编程语言开发的简单应用程序,旨在帮助用户管理并设置定时关闭的任务。这个任务管理器具备基础的进程管理和定时任务功能,允许用户监控系统中的运行进程,并设定...

    分布式任务调度系统调研

    1. **任务类型限制**:目前仅支持Shell脚本或命令的执行,不支持Java或其他编程语言编写的任务。 2. **动态任务管理**:虽然支持修改现有任务的参数,但对于新任务的动态添加和支持分片等功能仍有待增强。 #### LTS...

    简易定时器.rar

    【简易定时器】是一款基于C++编程语言开发的简单易用的定时软件。这款软件的主要功能是帮助用户设定特定的时间间隔,以便在指定的时刻触发提醒或者执行预设的任务。作为一个C++编程的基础示例,它展示了如何利用时间...

    MsqPHP框架MsqPHP.zip

    定时任务支持(未成品) 队列支持(猜想中) 简易测试类(伪成品)(不支持html页面测试,无法解决链式操作测试繁杂) 标签:MsqPHP Web框架

    定时提醒工具

    本项目名为“定时提醒工具”,显然旨在为用户提供一个简单易用的定时通知功能。接下来,我们将深入探讨定时提醒工具的核心技术、设计原理以及可能实现的方法。 1. **TIMER控件**: TIMER控件是许多编程环境中的一...

    python源码-案例框架-实例-04 简易时钟.zip

    在本压缩包“python源码-案例框架-实例-04 简易时钟.zip”中,包含了一个关于Python编程的实践项目:一个简易时钟应用。这个项目旨在帮助学习者理解如何利用Python来创建实时显示时间的程序。下面我们将深入探讨与这...

    WTimer定时提醒工具软件

    【WTimer定时提醒工具软件】是一款简易而实用的定时提醒软件,主要功能是帮助用户设置定时事件并以声音提醒的方式通知用户。它以其便捷的操作和自定义化的声音设定,为日常时间管理提供了便利。 首先,关于软件的...

    .net简易网站

    而对于访客统计,可以创建定时任务或在每个请求处理后更新数据库。 安全方面,匿名登录通常采用Token认证机制。ASP.NET提供了OAuth、JWT(JSON Web Tokens)等认证方式,允许用户无须提供用户名和密码即可访问受...

    java简易时钟

    总结来说,创建一个Java简易时钟涉及了Swing GUI编程、事件处理、定时任务、日期和时间处理以及图形绘制等多个方面。对于初学者而言,这是一个很好的实践项目,可以帮助他们巩固基础知识并理解面向对象编程的概念。...

    基于单片机的简易shell

    5. **中断处理与多任务**:虽然简易shell可能不涉及复杂的多任务调度,但理解中断处理机制仍然重要,因为shell可能需要响应来自硬件的中断,例如按键输入或定时事件。 6. **错误处理**:为了提高用户友好性,简易...

    一个比较简单的报时器

    在Python中,可以使用`threading`库,而在JavaScript中,由于单线程特性,可能需要借助Web Workers。 7. **通知机制**: 当计时到达预设时间时,报时器可能需要发出提醒,这可以通过声音、弹窗或者振动等形式。在...

    c# 闹铃(简易版)

    标题"**C# 闹钟(简易版)**"表明我们的目标是构建一个基础的定时提醒功能,而描述提示我们只需关注核心功能,不涉及复杂的视觉效果或特效。 C#是一种面向对象的、类型安全的编程语言,广泛应用于Windows桌面应用、...

    Android简易日历

    `AlarmManager`可以设置定时任务,当到达特定日期和时间时触发通知。同时,需要结合`NotificationManager`创建和显示通知,提醒用户即将发生的事件。 最后,**多线程**和**异步处理**在处理耗时操作时显得尤为重要...

    简易正弦波三角波方波发生器_ 源码

    ### 知识点详解:简易正弦波、三角波、方波发生器源码解析 #### 1. **基础知识概述** 在电子工程和信号处理领域,正弦波、三角波和方波是三种非常基本且重要的波形。它们在音频合成、测试信号生成、通信系统以及...

    简易学生管理系统(含简单的网络通讯)

    《简易学生管理系统——结合iOS与Django的网络通讯实践》 在信息技术日益发达的今天,学生管理系统已经成为教育机构日常管理的重要工具。本项目名为“简易学生管理系统”,它不仅实现了本地数据管理,更进一步通过...

    简易贪吃蛇 C#

    【简易贪吃蛇 C#】是一款基于C#编程语言实现的经典游戏项目,它将带你重温童年乐趣,同时深入了解C#编程的基本概念和技术。在这款游戏中,玩家操作一条蛇,通过移动来吃食物,每次吃掉食物后,蛇的长度会增加,游戏...

    秋招马上开始了,不知道怎么写简历的小伙伴快来这吧,这里有一个简洁而不简单的简历模板简历面试这里是一个狠标准的校招面试简历

    - 结合Quartz和crontab实现定时告警任务配置。 - 集成SpringBoot Mail、阿里云短信服务和钉钉API,向用户发送告警信息。 - 利用Postman对部分业务接口进行功能测试。 2. **冬奥会网约车风险监测系统 - 国家重点...

    Python-简易的模型监控界面定期更新的用户信用分及特征分布

    5. **Web界面**:"simple-model-monitor-master"可能是一个简单的Web应用框架,如Flask或Django的项目结构。Web界面可以展示模型的性能指标,如AUC-ROC曲线、准确率等,并实时更新特征分布图。用户可以通过这个界面...

    简易便签(可设置透明度)

    在描述中提到的“C#写的简单便签”,暗示了这个软件是用C#语言编写的,可能利用了Windows Forms或WPF(Windows Presentation Foundation)这些.NET框架来构建用户界面。Windows Forms适合快速开发传统的桌面应用程序...

    基于netty-socketio的简易聊天室.zip

    本项目“基于netty-socketio的简易聊天室”利用了SpringBoot框架和Socket.IO库,构建了一个简单的多人在线聊天平台。下面将详细阐述相关知识点。 首先,**Socket.IO** 是一个为实时应用提供跨平台兼容的库,它允许...

Global site tag (gtag.js) - Google Analytics