spring boot 定时任务

好久没写了。今天搞一下spring boot 的定时任务。

定时任务顾名思义,就是定时执行。

如何使用定时任务?

使用spring boot 定时任务需要:

1、开启定时任务:在启动类添加@EnableScheduling注解。

2、创建一个被spring 管理的bean组件。在定时任务的方法上添加注解@Scheduled。

例如:

@Component
public class MailTask {
	@Scheduled(fixedRate=5000)
	public void sendMail() {
		log.info("第{}次定时发送邮件,现在时间:{}",sendMailCount++,JSONObject.toJSONStringWithDateFormat(new Date(),"yyyy-MM-dd HH:mm:ss,sss"));
	}

如何设置定时任务的定时?

定时任务的时间设置使用@Scheduled注解的几个属性来实现。

举栗:

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.wm.springboot.sc.service.EmailService;

import lombok.extern.slf4j.Slf4j;

/**
 * 定时任务
 * @author maybe
 */
@Slf4j
@Component
public class MailTask {

	@Autowired
	private EmailService emailService;
	
	private int sendMailCount = 1;
	private int testCronCount = 1;
	private int testFixedRate = 1;
	private int testFixedDelay = 1;
	
	/**
	 * initialDelay第一次延迟10秒执行,后续以重星开始为时间点,延迟5秒执行。
	 * 所有时间以毫秒为单位
	 */
	@Scheduled(fixedRate=5000,initialDelay = 10000)
	public void sendMail() {
		log.info("第{}次定时发送邮件,现在时间:{}",sendMailCount++,JSONObject.toJSONStringWithDateFormat(new Date(),"yyyy-MM-dd HH:mm:ss,sss"));
//		emailService.sendMail(new Emails("240918567@qq.com", "83321164@qq.com", "测试定时任务", msgText, isEnclosure))
	}
	
	/**
	 * cron:时间表达式
	 */
	@Scheduled(cron="0/3 15-20 11,12 * * *")
	public void testCron() {
		log.info("第{}次测试cron定时任务-----",testCronCount++);
	}
	
	/**
	 * fixedRate 上一次开始执行时间点之后延迟多少秒执行
	 */
	@Scheduled(fixedRate=5000)
	public void testFixedRate(){
		try {
			log.info("测试fixedRate,1111111111-----{}",testFixedRate++);
			Thread.sleep(3000);
			log.info("测试fixedRate,2222222222");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * fixedDelay 上一次执行完毕时间点后延迟执行
	 */
	@Scheduled(fixedDelay=5000)
	public void testFixedDelay() {
		try {
			log.info("测试fixedDelay定时任务333333333-----{}",testFixedDelay++);
			Thread.sleep(3000);
			log.info("测试fixedDelay定时任务444444444");
		} catch (InterruptedException e) {
			e.printStackTrace();  
		}
	}
}


这时候发现一个问题,就是我们执行定时任务都是一个线程执行的。


所以,如果需要多线程执行,需要配定时任务配置类,设置线程数。

import java.util.concurrent.Executors;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

/**
 * 定时任务配置类
 * 配置定时任务的并发数
 * @author maybe
 */
@Configuration
public class ScheduleConfig implements SchedulingConfigurer{

	@Override
	public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
		taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
	}
}

这时候再次执行:



这里多线程执行如果自己写一个线程来执行可不可以呢?

我试了一下,写一个线程是可以的。但是对于fixedDelay会有一个问题就是,他会和fixedRate一样,使用开始时间的后几秒,作为执行时间点。我觉得这可能和每次执行都是一个独立线程有关。具体还需要去学习研究一下。


cron时间表达式

这段是网上找的:

        Seconds : 可出现", - * /"四个字符,有效范围为0-59的整数
Minutes : 可出现", - * /"四个字符,有效范围为0-59的整数
Hours : 可出现", - * /"四个字符,有效范围为0-23的整数
DayofMonth : 可出现", - * / ? L W C"八个字符,有效范围为0-31的整数
Month : 可出现", - * /"四个字符,有效范围为1-12的整数或JAN-DEc
DayofWeek : 可出现", - * / ? L C #"四个字符,有效范围为1-7的整数或SUN-SAT两个范围。1表示星期天,2表示星期一, 依次类推

Year : 可出现", - * /"四个字符,有效范围为1970-2099年


下面简单举几个例子:
"0 0 12 * * ?"    每天中午十二点触发
"0 15 10 ? * *"    每天早上10:15触发
"0 15 10 * * ?"    每天早上10:15触发
"0 * 14 * * ?"    每天从下午2点开始到2点59分每分钟一次触发
"0 0/5 14 * * ?"    每天从下午2点开始到2:55分结束每5分钟一次触发
"0 0/5 14,18 * * ?"    每天的下午2点至2:55和6点至6点55分两个时间段内每5分钟一次触发
"0 0-5 14 * * ?"    每天14:00至14:05每分钟一次触发
"0 10,44 14 ? 3 WED"    三月的每周三的14:10和14:44触发
"0 15 10 ? * MON-FRI"    每个周一、周二、周三、周四、周五的10:15触发

* : 表示匹配该域的任意值,比如在秒*, 就表示每秒都会触发事件。;
? : 只能用在每月第几天和星期两个域。表示不指定值,当2个子表达式其中之一被指定了值以后,为了避免冲突,需要将另一个子表达式的值设为“?”;
- : 表示范围,例如在分域使用5-20,表示从5分到20分钟每分钟触发一次  
/ : 表示起始时间开始触发,然后每隔固定时间触发一次,例如在分域使用5/20,则意味着5分,25分,45分,分别触发一次.  
, : 表示列出枚举值。例如:在分域使用5,20,则意味着在5和20分时触发一次。  
L : 表示最后,只能出现在星期和每月第几天域,如果在星期域使用1L,意味着在最后的一个星期日触发。  
W : 表示有效工作日(周一到周五),只能出现在每月第几日域,系统将在离指定日期的最近的有效工作日触发事件。注意一点,W的最近寻找不会跨过月份  
LW : 这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。  

# : 用于确定每个月第几个星期几,只能出现在每月第几天域。例如在1#3,表示某月的第三个星期日。


好了,大概就这么多。spring boot还是有很多功能的。

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34083066/article/details/79960255
个人分类: spring java
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭