springBoot整合定时任务和异步任务处理

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触发

在Spring Boot中,可以使用@Scheduled注解来实现定时任务,可以结合@Async注解来实现多线程异步。 首先,需要在启动类上添加@EnableAsync注解,开启异步支持。然后在要执行异步任务的方法上添加@Async注解。 接下来,可以使用Java中的Executor框架来创建线程池,用于执行异步任务。可以在应用程序中创建一个线程池,并使用@Async注解将任务提交给线程池执行。 下面是一个示例代码: ```java @Configuration @EnableAsync public class AsyncConfig { @Bean(name = "taskExecutor") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(20); executor.setQueueCapacity(30); executor.setThreadNamePrefix("MyAsyncThread-"); executor.initialize(); return executor; } } @Service public class MyService { @Async("taskExecutor") @Scheduled(cron = "0 0 12 * * ?") //每天中午12点执行 public void myAsyncTask() { //异步任务内容 } } ``` 在上面的示例中,我们创建了一个名为“taskExecutor”的线程池,并将其注入到MyService中的myAsyncTask方法中。该方法使用@Async注解来指示它应该在异步线程中执行。@Scheduled注解指定了任务执行的时间。 需要注意的是,@Async注解只有在调用该方法的类通过Spring容器进行管理时才会生效。如果通过new关键字手动创建对象,@Async注解将不起作用。 希望这可以帮助你完成Spring Boot定时任务整合多线程异步的实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值