前言:Java定时器目前主要有3种实现方式:JDK组件,Spring Task,Quartz框架。
1. JDK组件
(1) java.util.TimerTask
MyTimerTask.java:
public class MyTimerTask extends TimerTask { @Override public void run() { System.out.println("MyTimerTask, now: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); } public static void main(String[] args) { Timer timer = new Timer(); timer.schedule(new MyTimerTask(), 1000, 1000); //timer.cancel(); //停止调度器 } }
(2) java.util.concurrent.ScheduledThreadPoolExecutor(JDK5.0+之后推荐使用)
MyScheduledTask.java:
public class MyScheduledTask implements Runnable { public void run() { System.out.println("my scheduled task, now: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); } }
MyScheduledExecutor.java:
public class MyScheduledExecutor { public static void main(String[] args) { ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10); ScheduledFuture future = executor.scheduleWithFixedDelay(new MyScheduledTask(), 1000, 1000, TimeUnit.MILLISECONDS); //future.cancel(true); // 停止定时任务,Timer不能停止定时任务,只能关闭调度器 //executor.shutdown(); // 关闭调度器 } }
比较:java.util.concurrent.ScheduledThreadPoolExecutor比java.util.TimerTask更加灵活和高效。
2. Spring Task
(1) 配置方式实现
TaskJob.java:
@Service public class TaskJob { public void job1() { System.out.println("指定Spring定时任务1, now: " + new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(new Date())); } }
spring.xml:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:task="http://www.springframework.org/schema/task" ... xsi:schemaLocation=" ... http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <!-- 自动注入定时任务组件 --> <context:component-scan base-package="xxx" /> <!-- 定义定时任务调度策略 --> <task:scheduled-tasks> <task:scheduled ref="taskJob" method="job1" cron="0/1 * * * * ?" /> </task:scheduled-tasks> </beans>
(2) 注解方式实现
TaskJob2.java:
@Component public class TaskJob2 { /** * 每隔一秒执行一次 */ @Scheduled(cron="0/1 * * * * ?") public void job2() { System.out.println("注解方式使用spring定时任务框架, now: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); } }
spring.xml:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task" ... xsi:schemaLocation=" ... http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <!-- 自动注入定时任务组件 --> <context:component-scan base-package="xxx" /> <!-- 启动注解方式的定时任务 --> <task:annotation-driven /> </beans>
3. Quartz
Quartz是一个开源的,功能非常丰富的定时器框架,详见:http://www.quartz-scheduler.org/。
Quartz可以独立使用,也可以集成在Spring框架中,详见:http://projects.spring.io/spring-framework/。
(1) 独立使用Quartz(详见Quartz官方示例):
pom.xml:
<dependencies> <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> </dependencies>
定义定时任务,MyJob.java:
public class MyJob implements Job { public void execute(JobExecutionContext arg0) throws JobExecutionException { System.out.println("执行Quartz定时任务实现, now: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); } }
调度定时任务,MyJobSheduler:
public class MyJobSheduler { public static void main(String[] args) { try { JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("myJob").build(); Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1") .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever()) .build(); Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(job, trigger); scheduler.start(); } catch (SchedulerException e) { e.printStackTrace(); } } }
(2) Spring集成Quartz
如:http://docs.spring.io/spring/docs/5.0.0.M4/spring-framework-reference/htmlsingle/#scheduling-quartz 。
【实现比较】
实现方式 | 优点 | 缺点 |
JDK组件 | 无需引入第三方依赖,控制灵活 | 仅支持简单任务调度,不支持指定日期等复杂定时任务 |
Spring Task | 功能相对JDK方式全面(简单或指定日期等复杂任务调度),支持注解和配置2种方式 | Spring 3.x及以上版本才支持,详见: http://www.springframework.org/schema/task,且无法灵活控制任务启动或停止。 |
Quartz | 开源,功能全面且强大(简单或指定日期等复杂任务调度),可独立使用,也可以与Spring集成 必须在项目中引入quartz依赖 | 在项目中必须引入quartz依赖。 |
【使用总结】
1. J2EE项目
-- 未依赖Spring框架,建议使用Quartz。
-- 引入了Spring 3.x+,如果仅需要简单定时任务控制,建议使用Spring Task;否则建议使用Quartz。
-- 特别地,在Spring Boot项目中,根据需求可以灵活选择JDK,Spring Task或者Quartz。
2. 非J2EE项目
-- 简单定时任务控制,建议使用JDK实现:java.util.concurrent.ScheduledThreadPoolExecutor;否则建议使用Quartz。
附:Linux crontab
在Linux环境下,可以直接使用crontab程序实现简单的定时任务,比如定时全量备份MySQL数据库。
详见:https://wiki.archlinux.org/index.php/Cron_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)
【参考】
http://gong1208.iteye.com/blog/1773177 Spring定时任务的几种实现
http://www.cnblogs.com/liuyitian/p/4108391.html Spring cron 表达式
http://blog.csdn.net/ethanzhao/article/details/4406017 Linux crontab 命令格式与详细例子