JAVA定时任务
一、什么是定时任务:
定时任务是指调度程序在指定的时间或周期触发执行的任务
使用场景:发送邮件、统计、状态修改、消息推送、活动开启、增量索引
二、定时任务实现技术:
1. Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。使用较少。
2. Spring3.0以后自主开发的定时任务工具spring task,使用简单,支持线程池,可以高效处理许多不同的定时任务,除spring相关的包外不需要额外的包,支持注解和配置文件两种形式。 不能处理过于复杂的任务
3. 专业的定时框架quartz,功能强大,可以让你的程序在指定时间执行,也可以按照某一个频度执行,支持数据库、监听器、插件、集群
三、示例
1. Timer
/**
* java timer 测试类
* Created by gaozhy on 2017/6/24.
*/
public class JavaTimer {
public static void main(String[] args) {
try {
// 创建定时器
Timer timer = new Timer();
// 添加调度任务
// 安排指定的任务在指定的时间开始进行重复的 固定延迟执行
timer.schedule(new MyTask(),new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2017-06-24 22:31:10"),10*1000);
// 安排指定的任务在指定的延迟后开始进行重复的 固定速率执行
//timer.scheduleAtFixedRate(new MyTask(),new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2017-06-24 22:31:10"),10*1000);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
/**
* 任务类
* Created by gaozhy on 2017/6/24.
*/
public class MyTask extends TimerTask{
// 定义调度任务
public void run() {
System.out.println("log2:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
}
2. Spring Task
基于配置
/** * Spring Task 任务类 * Created by gaozhy on 2017/6/24. */ public class SpringTask { private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public void m1(){ System.out.println("m1:"+simpleDateFormat.format(new Date())); } public void m2(){ System.out.println("m2:"+simpleDateFormat.format(new Date())); } public void m3(){ System.out.println("m2:"+simpleDateFormat.format(new Date())); } }
<!--spring-task.xml配置--> <bean id="springTask" class="com.baizhi.task.SpringTask"></bean> <!--注册调度任务--> <task:scheduled-tasks> <!--延迟8秒 执行任务--> <!--<task:scheduled ref="springTask" method="m1" fixed-delay="8000" />--> <!--固定速度5秒 执行任务--> <!--<task:scheduled ref="springTask" method="m2" fixed-rate="5000"/>--> <!-- 使用cron表达式 指定触发时间 spring task 只支持6位的cron表达式 秒 分 时 日 月 星期 --> <task:scheduled ref="springTask" method="m3" cron="50-59 * * ? * *"/> </task:scheduled-tasks> <!--执行器配置--> <task:executor id="threadPoolTaskExecutor" pool-size="10" keep-alive="5"></task:executor> <!--调度器配置--> <task:scheduler id="threadPoolTaskScheduler" pool-size="10"></task:scheduler>
基于注解
/** * Spring Task 任务类 * Created by gaozhy on 2017/6/24. */ public class SpringAnnotationTask { private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); /* @Scheduled(fixedDelay = 8000) public void m1(){ System.out.println("m1:"+simpleDateFormat.format(new Date())); } @Scheduled(fixedRateString = "5000") public void m2(){ System.out.println("m2:"+simpleDateFormat.format(new Date())); } */ @Scheduled(cron = "0-30 * * * * ?") public void m3(){ System.out.println("m2:"+simpleDateFormat.format(new Date())); } }
<!--开启基于注解的spring task--> <task:annotation-driven></task:annotation-driven> <bean id="springAnnotationTask" class="com.baizhi.task.SpringAnnotationTask"></bean>
3. quartz
- 下载http://www.quartz-scheduler.org/downloads/
- 导入lib或maven依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
- 核心接口
a. scheduler 调度器
b. Job 任务
c. trigger 触发器
d. JobDetail 任务信息 trigger触发器
a. SimpleTrigger
b. CronTriggercron表达式: 秒 分 时 日 月 周 年
简单入门
/** * * Created by gaozhy on 2017/6/25. */ public class MyScheduler { public static void main(String[] args) { try { // 1. 创建调度器工厂 SchedulerFactory schedulerFactory = new StdSchedulerFactory(); // 2. 获取调度器 Scheduler scheduler = schedulerFactory.getScheduler(); // 3. 创建任务详情 JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("myJob","default").build(); // 4. 启动10秒后的时间 Date futureDate = DateBuilder.futureDate(10, DateBuilder.IntervalUnit.SECOND); // 5. 创建触发器 Trigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger","default").startAt(futureDate).build(); // 6. 注册任务详情和触发器 scheduler.scheduleJob(jobDetail,trigger); //7. 启动调度任务 scheduler.start(); } catch (SchedulerException e) { e.printStackTrace(); } } }
/** * Created by gaozhy on 2017/6/25. */ public class MyJob implements Job { private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("log:"+simpleDateFormat.format(new Date())); } }
基于simpleSchedule的定时任务
/** * 简单触发器 调度程序 * Created by Administrator on 2017/6/25 0025. */ public class SimpleTriggerScheduler { public static void main(String[] args) { try { StdSchedulerFactory factory = new StdSchedulerFactory(); Scheduler scheduler = factory.getScheduler(); JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("myJob","default").build(); // 指定触发器 // lucene 唐诗 // 1. 获取数据库每天新增的诗 // 2. 定时任务 每天零点触发 // 3. 任务方法 增量索引 // 简单定时 SimpleTrigger 间隔或者重复调用 Trigger trigger = TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10).withRepeatCount(10)).build(); scheduler.scheduleJob(jobDetail,trigger); scheduler.start(); } catch (SchedulerException e) { e.printStackTrace(); } } }
基于CronSchedule的定时任务
/** * 基于CronTrigger * Created by Administrator on 2017/6/25 0025. */ public class CronTriggerScheduler { public static void main(String[] args) { try { StdSchedulerFactory factory = new StdSchedulerFactory(); Scheduler scheduler = factory.getScheduler(); JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("myJob","default"). usingJobData("id",1).usingJobData("name","zs").build(); /** * 在cron表达式中 日和周中不能同时出现* * quartz cron表达式 6位或者7位 */ //Trigger trigger = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule("0 0 10 ? * 4#3")). Trigger trigger = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * ? * * 2017-2020")). withIdentity("myTrigger","default").build(); scheduler.scheduleJob(jobDetail,trigger); scheduler.start(); } catch (SchedulerException e) { e.printStackTrace(); } } }
Quartz和Spring整合
依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring-version}</version> </dependency>
任务类继承QuartzJobBean或实现Job接口
Spring.xml配置
<!--<bean id="user" class="User"></bean>--> <!--创建JobDetail--> <bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <!--指定任务类--> <property name="jobClass" value="com.baizhi.quartz4.MyJob"></property> <!--指定job中spring工厂的名字 指定后 可以在job类中获取spring工厂 --> <property name="applicationContextJobDataKey" value="applicationContext"></property> <property name="jobDataAsMap"> <map> <entry key="id" value="1"></entry> <entry key="name" value="zhangsan"></entry> <!--<entry key="user" value-ref="user"></entry>--> </map> </property> <!--当Job在没有可以使用的trigger的情况下 不删除--> <property name="durability" value="true"></property> </bean> <bean id="jobDetail1" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <!--指定任务类--> <property name="jobClass" value="com.baizhi.quartz4.MyJob1"></property> <!--当Job在没有可以使用的trigger的情况下 不删除--> <property name="durability" value="true"></property> </bean> <!-- 创建触发器 Simple Cron --> <!--注意 spring quartz整合 一个trigger只可以绑定一个JobDetail 一个jobDetail可以被多个Trigger所使用--> <bean id="trigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <!--绑定JobDetail--> <property name="jobDetail" ref="jobDetail"></property> <property name="cronExpression" value="0-30 * * * * ?"></property> </bean> <!--<bean id="" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> </bean>--> <bean id="trigger1" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <!--绑定JobDetail--> <property name="jobDetail" ref="jobDetail"></property> <property name="cronExpression" value="45-55 * * * * ?"></property> </bean> <!--注册trigger--> <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="trigger"></ref> <ref bean="trigger1"></ref> </list> </property> </bean>