SpringBoot 定时任务、异步任务


 

定时任务Schedule

eg. 每天凌晨1点自动统计昨天的流水(订单数、交易额),每月1号自动统计上月的流水。后台实现定时任务常见的方式有2种

  • quartz框架(任务调度)
  • springboot的schedule
     

SpringBoot自带定时任务功能,不需要额外添加依赖

1、引导类上加 @EnableScheduling

2、编写定时任务

@Component  //放到spring容器中
public class Xxx {

    @Scheduled(fixedRate = 5000)  //定时执行,参数指定间隔时间
    public void xxx(){

    }

}

 
间隔时间的几种指定方式

@Scheduled(fixedRate = 5000)  //每5000ms执行1次。间隔是距离上次执行开始

@Scheduled(fixedDelay = 5000) //上次执行结束,5000ms后再次执行。间隔是距离上次执行结束

// 和以上2种分别对应,只是值写成字符串形式
@Scheduled(fixedRateString = "5000") 
@Scheduled(fixedDelayString = "5000")


@Scheduled(cron = "0 0/10 * * * *")  //每隔10分钟执行1次

cron有6个字段,依次是

  • second
  • minute
  • hour
  • day of month
  • month
  • day of week

都是 0/x 的形式,表示每隔x时间执行1次,前面不指定的写0,后面不指定的写*

异步任务Async

异步任务可分为2类

  • 不需要返回结果:处理日志、发送邮件、短信…
  • 需要返回结果:比如用户支付订单要校验库存、用户余额、风控…都没有问题才允许支付订单

异步任务都是启动一条新线程来执行,当前线程不阻塞,提高效率。
 

1、引导类上加 @EnableAsync

2、封装异步任务

@Component  //放到spring容器中
@Async  //将类中的方法都标识为异步方法。如果不需要标注全部方法,在需要标注的方法上标注@Async即可
public class AsyncTask {

    // 不需要返回结果的
    public void task1(){
        //.....
    }

    // 需要返回结果的,泛型,可返回任何类型,此处返回String
    public Future<String> task2(){
        //......
        return new AsyncResult<>("ok");
    }

    public Future<String> task3(){
        //......
        return new AsyncResult<>("ok");
    }

}

 
3、使用异步任务

@Service
public class XxxService {
    @Resource
    private AsyncTask asyncTask;

    public void xxx(){
        //.....

        // 执行异步方法时,会启动一条新线程来执行,当前线程不阻塞
        asyncTask.task1();

        // 需要返回结果的
        Future<String> task2 = asyncTask.task2();
        Future<String> task3 = asyncTask.task3();

        // ......   //当前线程的其它代码

        //在当前线程需要使用异步任务的执行结果时,使用while(true)阻塞当前线程,等待异步任务的执行结果
        while(true){
            if (task2.isDone() && task3.isDone()){  //如果需要的异步任务都执行完了
                // 一些操作
                try {
                    if (task2.get().equals("ok") && task3.get().equals("ok")){  //get()获取异步任务返回的值
                        //....
                    }
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
                //.....

                break;  //当前线程继续放下执行
            }
        }
        //....
    }

}

猜你喜欢

转载自blog.csdn.net/chy_18883701161/article/details/106314007