Java中实现执行任务调度
Timer
jdk
提供的定时器工具Timer
- 单线程
- 可以指定延迟(开始执行的时间)、周期时间
- 可以调度指定的的需要执行的任务
1 | import java.util.Timer; |
定时器
1.通过线程池的方式来执行任务
2.可以设定时间颗粒度
函数 | 含义 |
---|---|
TimeUnit.DAYS | 天 |
TimeUnit.HOURS | 小时 |
TimeUnit.MINUTES | 分钟 |
TimeUnit.SECONDS | 秒 |
TimeUnit.MILLISECONDS | 毫秒 |
TimeUnit.NANOSECONDS | 毫微秒 |
TimeUnit.MICROSECONDS | 微秒 |
1 | import java.util.concurrent.Executors; |
SpringBoot定时器
SpringBoot中的任务调度,方便,快速
在SpringBoot的启动类(主入口)的
类
上添加注解@EnableScheduling
,加上注解以后,项目会自动添加对应的配置文件在需要使用任务调度的
类
上面加注解@Component
,使该类被Spring管理1
2
3
4
5
6
7import org.springframework.stereotype.Component;
public class Ds {
//方法1 {...}
//方法2 {...}
//....
}- 任务调度的方法上面加注解
@Scheduled
参数 含义 cron 时间表达式 fixedRate 上一个调用开始后再次调用的延时(再次调用时不需要等上一个调用执行完成) fixedDelay 上一个调用完成后再次调用的延时(再次调用时需要等上一个调用执行完成) initialDelay 第一次调用时的延迟时间 指定时间配置的完整格式为:
[秒] [分] [小时] [日] [月] [周] [年]
- 【
*
】星号:可以理解为每的意思,每秒,每分,每天,每月,每年… - 【
?
】问号:问号只能出现在日期和星期这两个位置,表示这个位置的值不确定,每天3点执行,所以第六位星期的位置,我们是不需要关注的,就是不确定的值。- 同时:日期和星期是两个相互排斥的元素,通过问号来表明不指定值。
- 比如,1月10日,比如是星期一,如果在星期的位置是另指定星期二,就前后冲突矛盾了。
- 【
-
】减号:表达一个范围,如在小时字段中使用“10-12
”,则表示从10到12点,即10,11,12
- 【
,
】逗号:表达一个列表值,如在星期字段中使用“1,2,4
”,则表示星期一,星期二,星期四
- 【
/
】斜杠:如:x/y
,x是开始值,y是步长,- 比如在第一位(秒) “
0/15
”就是,从0秒开始,每15秒,最后就是0,15,30,45,60
- 另外:
*/y
,等同于0/y
- 比如在第一位(秒) “
- 时间表达式校验网站:在线校验工具
属性 含义 fixedRate = 1000
每秒执行一次,单位毫秒 0 0 10,14,16 * * ?
每天10点、14点、16点 触发 0 0/30 9-17 * * ?
朝九晚五工作时间内每半小时触发 0 0 12 ? * WED
表示每个星期三中午12点触发 0 0 12 * * ?
每天中午12点触发 0 15 10 ? * *
每天上午10:15触发 0 15 10 * * ?
每天上午10:15触发 0 15 10 * * ? *
每天上午10:15触发 0 15 10 * * ? 2005
2005年的每天上午10:15触发 0 * 14 * * ?
在每天下午2点到下午2:59期间的每1分钟触发 0 0/5 14 * * ?
在每天下午2点到下午2:55期间的每5分钟触发 0 0/5 14,18 * * ?
在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 0 0-5 14 * * ?
在每天下午2点到下午2:05期间的每1分钟触发 0 10,44 14 ? 3 WED
每年三月的星期三的下午2:10和2:44触发 0 15 10 ? * MON-FRI
周一至周五的上午10:15触发 0 15 10 15 * ?
每月15日上午10:15触发 0 15 10 L * ?
每月最后一日的上午10:15触发 0 15 10 ? * 6L
每月的最后一个星期五上午10:15触发 0 15 10 ? * 6L 2002-2005
2002年至2005年的每月的最后一个星期五上午10:15触发 0 15 10 ? * 6#3
每月的第三个星期五上午10:15触发 - 【
调用执行1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
public class Demo {
//每1秒执行一次该方法
public void test() {
System.out.println("------定时调度------");
}
//每天12点执行一次该方法
public void test2() {
System.out.println("------定时调度2------");
}
}
通常情况下,任务调度需要配合异步功能,所以类只需要再添加一个注解@EnableAsync1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18import org.springframework.stereotype.Component;
import org.springframework.scheduling.annotation.EnableAsync;
public class Ds {
//每1秒执行一次该方法
public void test() {
System.out.println("------定时调度------");
}
//每天12点执行一次该方法
public void test2() {
System.out.println("------定时调度2------");
}
}
SpringBoot注解 番外篇
在这里,我重点解释下这个注解方式
如果直接把@EnableScheduling
注解写到启动类中,这样的话就会很死板
所以得想个办法,不在启动类中加注解,而是通过配置文件 能人为控制定时任务的开启或关闭
进入@EnableScheduling
,看到引入的 SchedulingConfiguration.class
,进去后不难发现,该类注入了ScheduledAnnotationBeanPostProcessor
知道了上面这些,所以现在我们需要做的就是通过配置来控制定时任务
手动编写一个配置类来控制(不需要方法),如下:
1 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
application.yml
添加个配置,通过true|false
来控制TaskEnableSchedulingConfig
这个类
1 | # 定时任务开启状态 |
这样,就能通过application.yml
配置文件来控制是否要开启定时任务了