1.创建Maven项目,填写pom.xml文件添加jar包
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
</dependencies>
2.创建spring配置文件spring-mvc-task.xml
2.1创建spring-mvc-task.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd">
</beans>
2.1.1.1采用bean方式创建定时任务
<task:annotation-driven />
<bean id="taskTest" class="com.dhrtec.lab.task.extractExecute" ></bean>
<task:scheduled-tasks >
<!-- 0 15 10 ? * * 每天上午十点十五预警
0 0 12 * * ? 每天中午12点触发
0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
<task:scheduled ref="taskTest" method="say" cron="0 30 9 * * ?" />
0 */1 * * * ? 每隔1分钟执行一次: -->
<task:scheduled ref="taskTest" method="say" cron="0 0 22 ? * *" />
</task:scheduled-tasks>
2.1.1.2新建任务类extractExecute
/**
* 定时任务发起方法
* @author:lin
*/
public void say() {
try {
List<SyncStepVO> res = taskService.createSyncStep();
} catch (Exception e) {
e.printStackTrace();
}
}
2.1.2.1采用注解方式创建定时任务
2.1.2.2在spring-mvc-task.xml配置
<context:annotation-config />
<!-- 多线程 -->
<task:annotation-driven scheduler="myScheduler" executor="myExecutor"/>
<!-- 调度线程池配置 -->
<task:scheduler id="myScheduler" pool-size="5"/>
<!-- 执行线程池配置 -->
<task:executor id="myExecutor" pool-size="5"/>
<context:component-scan base-package="com.dhrtec.lab.task" />
<!-- 单线程 -->
<task:annotation-driven scheduler="myScheduler" executor="myExecutor"/>
<context:component-scan base-package="com.dhrtec.lab.task" />
2.1.2.2新建任务类extractExecute
/**
* 采用注解方式启动
*/
@Component("extractExecute")
public class extractExecute {
//采用注解形式
//每分钟的5-7秒每秒执行一次执行,21-25秒每秒执行一次
@Scheduled(cron = "5-7,21-25 * * * * ?")
public void print2(){
System.out.println("注解形式--print2,"+new SimpleDateFormat("hh:mm:ss").format(new Date())+".......");
}
}
3.cron表达式注解
秒: 必填项,范围0-59,支持的特殊符号 , - * /
分: 必填项,范围0-59,支持的特殊符号 , - * /
时: 必填项,范围0-23,支持的特殊符号 , - * /
日期: 必填项,范围1-31,支持的特殊符号 ,- * ? / L W C
月: 必填项,范围1-12(JAN-DEC),支持的特殊符号 , - * /
星期: 必填项,允许1~7 (SUN-SAT),1代表星期天(一星期的第一天),支持的特殊符号 , - * ? / L C #
年: 可选项,范围1970~2099,支持的特殊符号 , - * /
1、*:代表所有可能的值
2、-:指定范围 例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次
3、,:列出枚举 例如在分钟里,"5,15"表示5分钟和20分钟触发
4、/:指定增量 例如在分钟里,"3/15"表示从3分钟开始,没隔15分钟执行一次
5、?:表示没有具体的值,使用?要注意冲突(日期和星期的冲突)
6、L:表示last,例如星期中表示7或SAT,月份中表示最后一天31或30,6L表示这个月倒数第6天,FRIL表示这个月的最后一个星期五
7、W:只能用在月份中,表示最接近指定天的工作日 例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份
8、LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五
9、#:只能用在星期中,表示这个月的第几个周几,例如6#3表示这个月的第3个周五
10、C:允许在日期域和星期域出现。这个字符依靠一个指定的“日历”。也就是说这个表达式的值依赖于相关的“日历”的计算结果,如果没有“日历”关联,则等价于所有包含的“日历”。如:日期域是“5C”表示关联“日历”中第一天,或者这个月开始的第一天的后5天。星期域是“1C”表示关联“日历”中第一天,或者星期的第一天的后1天,也就是周日的后一天(周一)
4.关于注解上参数
task:scheduler 参数的线程池,是为了根据任务总数来分配调度线程池的大小
task:executor 是为了某个任务如果要异步的执行时,实现当前任务内的多线程并发。
①我是一个执行完后,隔一小时就会执行的任务
fixedDelay是指,这个函数每隔一段时间就会被调用(我们这里设置的是一天),不管再次调度的时候,这个方法是在运行还是结束了
②我是一个每隔一天就会执行一次的调度任务
fixedRate是指,而前者就要求是函数运行结束后开始计时的
③我是第一次调用前需要等待的时
nitialDelay是指,第一次调用前需要等待的时间,这里表示被调用后的,推迟一秒再执行,这适合一些特殊的情况。
④@Async
有时候我们会调用一些特殊的任务,任务会比较耗时,重要的是,我们不管他返回的后果。这时候我们就需要用这类的异步任务啦,调用后就让他去跑,不堵塞主线程,我们继续干别的。
相对于@scheduled,这个可以有参数和返回个结果,因为这个是我们调用的,而调度的任务是spring调用的。
异步方法不能内部调用,只能像上面那样,外部调用,否则就会变成阻塞主线程的同步任务啦!这个坑我居然跳下去了!例如下面这样的。
public void AsyncTask(){
public void fakeAsyncTaskTest(){
doSomeHeavyBackgroundTask(4000);
printLog();
//你会发现,当你像这样内部调用的时候,居然是同步执行的,不是异步的!!
}
@Async
public void doSomeHeavyBackgroundTask(int sleepTime) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void printLog() {
System.out.println(" i print a log ");
}
}