1 springboot 定时任务schedule
简介:
1,常见定时任务 Java自带的java.util.timer类
timer:配置比较麻烦,时间延后问题
timertask:不推荐
2,Quartz框架 (ssm框架使用)
配置更简单
xml或者注解
3,Springboot使用注解方式 (springboot使用)
1) 启动类里面 @EnableScheduling 开启定时任务,自动扫描
2) 定时任务业务类 加注解 @Component 被容器扫描
3) 定时执行的方法加上注解 @Scheduled(fixedRate = 2000) 定期(每两秒)执行一次
启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling //开启定时任务
public class ScheduleApplication {
public static void main(String[] args) {
SpringApplication.run(ScheduleApplication.class, args);
}
}
定时任务业务类
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class TestTask {
@Scheduled(fixedRate = 2000) //两秒执行一次
public void sum(){
System.out.println("当前时间"+new Date());
}
}
打印结果
当前时间Tue Jan 07 09:16:20 CST 2020
当前时间Tue Jan 07 09:16:22 CST 2020
当前时间Tue Jan 07 09:16:24 CST 2020
当前时间Tue Jan 07 09:16:26 CST 2020
当前时间Tue Jan 07 09:16:28 CST 2020
当前时间Tue Jan 07 09:16:30 CST 2020
当前时间Tue Jan 07 09:16:32 CST 2020
当前时间Tue Jan 07 09:16:34 CST 2020
当前时间Tue Jan 07 09:16:36 CST 2020
常用定时任务配置
常用定时任务表达式配置和在线生成器
1,cron定时任务表达式@Scheduled(cron="*/1*****")表示每秒
ps:crontab 参考工具 https://tool.lu/crontab/
2,fixedRate:定时多久执行一次(上一次开始执行时间点后xx秒再次执行)
3,fixedDelay:定时多久执行一次(上一次执行结束时间点后xx秒再次执行)
4,fixedDelayString:字符串形式,可以通过配置文件指定
springboot异步任务实战
1.什么是异步任务和使用场景:适用于处理log,发送邮件,短信…等
下单接口->查询库存 100
余额校验 150
风控用户 100
…
2. 启动类里面使用@EnabledAsync注解开启功能,自动扫描
3. 定义异步任务类并使用@Component标记组件被容器扫描,异步方法加上@Async
注意点:
1) 要把异步任务封装到类里面,不能直接写到controller
2) 增加Future<String>返回结果 AsyncResult<String>(“task执行完成”)
3) 如果需要拿到结果,需要判断全部的 task.isDone()
4. 通过注入方式,注入到controller里面,如果测试前后区别则改为同步,则把Async注释掉
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import java.util.concurrent.Future;
/**
* 异步任务业务类
*/
@Component
@Async
public class AsyncTask {
public void task1() throws InterruptedException {
long begin = System.currentTimeMillis();
Thread.sleep(1000L);
long end = System.currentTimeMillis();
System.out.println("任务1耗时=" + (end - begin));
}
public void task2() throws InterruptedException {
long begin = System.currentTimeMillis();
Thread.sleep(2000L);
long end = System.currentTimeMillis();
System.out.println("任务2耗时=" + (end - begin));
}
public void task3() throws InterruptedException {
long begin = System.currentTimeMillis();
Thread.sleep(3000L);
long end = System.currentTimeMillis();
System.out.println("任务3耗时=" + (end - begin));
}
//获取异步结果
public Future<String> task4() throws InterruptedException {
long begin = System.currentTimeMillis();
Thread.sleep(1000L);
long end = System.currentTimeMillis();
System.out.println("任务4耗时=" + (end - begin));
return new AsyncResult<>("任务4");
}
public Future<String> task5() throws InterruptedException {
long begin = System.currentTimeMillis();
Thread.sleep(1000L);
long end = System.currentTimeMillis();
System.out.println("任务5耗时=" + (end - begin));
return new AsyncResult<>("任务5");
}
public Future<String> task6() throws InterruptedException {
long begin = System.currentTimeMillis();
Thread.sleep(1000L);
long end = System.currentTimeMillis();
System.out.println("任务6耗时=" + (end - begin));
return new AsyncResult<>("任务6");
}
}
import com.javagirl.schedule.task.AsyncTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;
@RestController
@RequestMapping("/api/v1")
public class UserController {
@Autowired
AsyncTask task;
@GetMapping("async_task")
public Map exeTask() {
Map<String, Object> map = new HashMap<>();
Map<String, Object> map1 = new HashMap<>();
long begin = System.currentTimeMillis();
try {
task.task1();
task.task2();
task.task3();
map1.put("result", "success");
} catch (InterruptedException e) {
map1.put("result", e.getMessage());
e.printStackTrace();
}
long end = System.currentTimeMillis();
long total = end - begin;
System.out.println("map1执行总耗时=" + total);
map1.put("map1执行总耗时", total);
Map<String, Object> map2 = new HashMap<>();
try {
long begin1 = System.currentTimeMillis();
Future<String> task4 = task.task4();
Future<String> task5 = task.task5();
Future<String> task6 = task.task6();
for (; ; ) {
if (task4.isDone() && task5.isDone() && task6.isDone()) {
break;
}
}
long end1 = System.currentTimeMillis();
long totaol = end1 - begin1;
System.out.println("map2总耗时=" + totaol);
map2.put("map2执行总耗时", totaol);
map2.put("result", "success");
} catch (InterruptedException e) {
map2.put("result", e.getMessage());
e.printStackTrace();
}
map.put("map1", map1);
map.put("map2", map2);
return map;
}
}
结果
{
"map2":{
"result":"success",
"map2执行总耗时":1006
},
"map1":{
"result":"success",
"map1执行总耗时":4
}
}
//控制台
map1执行总耗时=4
任务6耗时=1000
任务1耗时=1000
任务5耗时=1000
任务4耗时=1000
map2总耗时=1006
任务2耗时=2000
任务3耗时=3000
//spring cron 常用实例
0 0 10,14,16 * * ? 每天上午10点,下午2点,4点
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触发