重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
java定时任务有三种:
创新互联-成都网站建设公司,专注网站设计、成都网站制作、网站营销推广,国际域名空间,网页空间,网站托管、服务器租用有关企业网站制作方案、改版、费用等问题,请联系创新互联。
- JDK自带 :JDK自带的Timer以及JDK1.5+ 新增的ScheduledExecutorService;
- Quartz :简单却强大的JAVA作业调度框架
- Spring3.0以后自带的task :可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多;
代码参考:
JDK 自带的定时器实现
schedule(TimerTask task, Date time) 特定时间执行
public static void main(String[] args) {
for (int i = 0; i 10; ++i) {
new Timer("timer - " + i).schedule(new TimerTask() {
@Override
public void run() {
println(Thread.currentThread().getName() + " run ");
}
}, new Date(System.currentTimeMillis() + 2000));
}
}
Quartz 定时器实现
2.1 通过maven引入依赖(这里主要介绍2.3.0) 注意:shiro-scheduler中依赖的是1.x版本 如果同时使用会冲突
!-- --
dependency
groupIdorg.quartz-scheduler/groupId
artifactIdquartz/artifactId
version2.3.0/version
/dependency
2.2 创建Job类
public class TestJob implements Job{
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
println(Thread.currentThread().getName() + " test job begin " + DateUtil.getCurrentTimeStr());
}
}
2.3 调度任务
public static void main(String[] args) throws InterruptedException, SchedulerException {
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
// 开始
scheduler.start();
// job 唯一标识 test.test-1
JobKey jobKey = new JobKey("test" , "test-1");
JobDetail jobDetail = JobBuilder.newJob(TestJob.class).withIdentity(jobKey).build();
Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("test" , "test")
// 延迟一秒执行
.startAt(new Date(System.currentTimeMillis() + 1000))
// 每隔一秒执行 并一直重复
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
.build();
scheduler.scheduleJob(jobDetail , trigger);
Thread.sleep(5000);
// 删除job
scheduler.deleteJob(jobKey);
}
3.Spring 相关的任务调度
3.1 配置文件实现
spring-schedule.xml
task:scheduler id="myScheduler" pool-size="10" /
task:scheduled-tasks scheduler="myScheduler"
task:scheduled ref="job" method="test" cron="0 * * * * ?"/
/task:scheduled-tasks
3.2注解实现
spring-schedule.xml
task:scheduler id="myScheduler" pool-size="10" /
// 启用注解
task:annotation-driven scheduler="myScheduler"/
@Component
public class Task{
@Scheduled(cron="0/5 * * * * ? ") //每5秒执行一次
public void execute(){
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(DateTime.now().toDate())+"*********B任务每5秒执行一次进入测试");
}
}
不要直接用java来操作修改 job。而是要写一个存储过程来修改 job。然后通过 java 调用存储过程,并把时间参数传入到存储过程中,这样就可以搞定了
例如:
/**
* @author kevin zhou
*
* 在Java中实现Job Scheduling
* 创建日期 2004-7-13
*/
import java.util.TimerTask;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
public class ReportGenerator extends TimerTask{
/* (非 Javadoc)
* @see java.util.TimerTask#run()
*/
public void run() {
System.out.println("Generating report");
}
}
class MainApplication {
public static void main(String[] args) {
Timer timer=new Timer();
Calendar date = Calendar.getInstance();
date.set(
Calendar.DAY_OF_WEEK,
Calendar.SUNDAY
);
date.set(Calendar.HOUR, 0);
date.set(Calendar.MINUTE, 0);
date.set(Calendar.SECOND, 0);
date.set(Calendar.MILLISECOND, 0);
// Schedule to run every Sunday in midnight
timer.schedule(
new ReportGenerator(),
date.getTime(),
1000 * 60 * 60 * 24 * 7
);
}
}
此处简单解释一下,在此例子中ReportGenerator继承java.util.TimerTask,它又继承了java.lang.Runnable,我们需要覆盖run()方法。
调用时用schedule()方法让它每周日0点0分执行,避开服务器高峰,实现Job Scheduling的目的。
补充:Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。
第一步:引包
要使用Quartz,必须要引入以下这几个包:
1、log4j-1.2.16
2、quartz-2.1.7
3、slf4j-api-1.6.1.jar
4、slf4j-log4j12-1.6.1.jar
这些包都在下载的Quartz包里面包含着,因此没有必要为寻找这几个包而头疼。
第二步:创建要被定执行的任务类
这一步也很简单,只需要创建一个实现了org.quartz.Job接口的类,并实现这个接口的唯一一个方法execute(JobExecutionContext arg0) throws JobExecutionException即可。如:
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class myJob implements Job {
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
System.out.println(sdf.format(new Date()));
}
}
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class myJob implements Job {
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
System.out.println(sdf.format(new Date()));
}
}
这个例子很简单,就不用解说了。
第三步:创建任务调度,并执行
这一步应该算是最难的一步的,但其实是非常简单的,直接上代码
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
public class Test {
public void go() throws Exception {
// 首先,必需要取得一个Scheduler的引用
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
//jobs可以在scheduled的sched.start()方法前被调用
//job 1将每隔20秒执行一次
JobDetail job = newJob(myJob.class).withIdentity("job1", "group1").build();
CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("0/20 * * * * ?")).build();
Date ft = sched.scheduleJob(job, trigger);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
System.out.println(job.getKey() + " 已被安排执行于: " + sdf.format(ft) + ",并且以如下重复规则重复执行: " + trigger.getCronExpression());
// job 2将每2分钟执行一次(在该分钟的第15秒)
job = newJob(myJob.class).withIdentity("job2", "group1").build();
trigger = newTrigger().withIdentity("trigger2", "group1").withSchedule(cronSchedule("15 0/2 * * * ?")).build();
ft = sched.scheduleJob(job, trigger);
System.out.println(job.getKey() + " 已被安排执行于: " + sdf.format(ft) + ",并且以如下重复规则重复执行: "+ trigger.getCronExpression());
// 开始执行,start()方法被调用后,计时器就开始工作,计时调度中允许放入N个Job
sched.start();
try {
//主线程等待一分钟
Thread.sleep(60L * 1000L);
} catch (Exception e) {}
//关闭定时调度,定时器不再工作
sched.shutdown(true);
}
public static void main(String[] args) throws Exception {
Test test = new Test();
test.go();
}
}
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
public class Test {
public void go() throws Exception {
// 首先,必需要取得一个Scheduler的引用
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
//jobs可以在scheduled的sched.start()方法前被调用
//job 1将每隔20秒执行一次
JobDetail job = newJob(myJob.class).withIdentity("job1", "group1").build();
CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("0/20 * * * * ?")).build();
Date ft = sched.scheduleJob(job, trigger);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
System.out.println(job.getKey() + " 已被安排执行于: " + sdf.format(ft) + ",并且以如下重复规则重复执行: " + trigger.getCronExpression());
// job 2将每2分钟执行一次(在该分钟的第15秒)
job = newJob(myJob.class).withIdentity("job2", "group1").build();
trigger = newTrigger().withIdentity("trigger2", "group1").withSchedule(cronSchedule("15 0/2 * * * ?")).build();
ft = sched.scheduleJob(job, trigger);
System.out.println(job.getKey() + " 已被安排执行于: " + sdf.format(ft) + ",并且以如下重复规则重复执行: "+ trigger.getCronExpression());
// 开始执行,start()方法被调用后,计时器就开始工作,计时调度中允许放入N个Job
sched.start();
try {
//主线程等待一分钟
Thread.sleep(60L * 1000L);
} catch (Exception e) {}
//关闭定时调度,定时器不再工作
sched.shutdown(true);
}
public static void main(String[] args) throws Exception {
Test test = new Test();
test.go();
}
}
OK了,Job1和Job2就会被安排为定时执行了。此时程序是可以执行的了,但是可能会输出WARN级别日志,这是因为没有加log4j的配置文件,加上配置文件,就OK了。这里需要说明的地方只有一个,其它的可以直接Copy到您的项目里面。看代码:
CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("0/20 * * * * ?")).build();
CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("0/20 * * * * ?")).build();
如果用java的类Time定时器,就是写在java文件里
如果是用spring的定时任务,就是写在xml里