SpringBoot学习篇11[异步任务、定时任务]

1.异步任务

在项目开发中,针对耗时业务逻辑,往往采用多线程来处理此任务。在Spring中使用异步任务极为方便,只需要一个@Async注解即可将任务加入线程池运行,极大的提高了开发效率。

1.1 使用异步任务

默认情况下,无需做任何额外配置,只需要以下两步便可使用SpringBoot的异步任务:

  • 在启动类加上@EnableAsync注解,开启注解使用异步任务的功能;
  • 在想要异步执行的方法前加上@Async注解,同时需要将该方法所在类注入Spring IOC容器,该方法在被调用时将异步执行。

启动类代码:

@SpringBootApplication
@EnableAsync
public class SpringBootTaskApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootTaskApplication.class, args);
    }

}

异步任务代码如下:

@Service
public class AsyncService {

    @Async
    public void  ProtocolInterpreter()
    {
        try {
            //模拟耗时操作
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(Thread.currentThread().getName() + ":协议解析完成");

    }

}

调用异步任务:

@RestController
public class HelloController {

    @Autowired
    AsyncService asyncService;

    @GetMapping("/hello")
    public String hello() {

        asyncService.ProtocolInterpreter();
        asyncService.ProtocolInterpreter();
        asyncService.ProtocolInterpreter();

        return "success";
    }
}

在浏览器访问地址http://localhost:8080/hello,success会被立刻返回
控制台打印:
在这里插入图片描述

1.2 配置异步任务

默认情况下,我们无需对SpringBoot的异步任务做任何特殊配置便可使用。但在一些要求比较高的应用中,SpringBoot的默认配置并不能满足我们的需求。这就需要我们手动配置了:

spring:
  task:
    execution:
      #配置线程池名称前缀
      thread-name-prefix: async-task-
      pool:
        #配置核心线程数,即线程池创建时的初始化大小,SpringBoot2.2默认值为8
        core-size: 10
        #配置最大线程数,SpringBoot2.2默认值为2147483647
        max-size: 100
        #配置缓冲队列数,用来存放待执行的任务,SpringBoot2.2默认值为2147483647
        #当待执行的线程数超过此队列大小时,Spring会将线程数增加,上限为所配置的最大线程数
        queue-capacity: 1000
        #配置线程最大空闲时间,线程空闲时间超过此时间,将被回收,SpringBoot2.2默认值为60(s)
        keep-alive: 20s

上面列出的配置文件中,我们做了以下配置:

  • thread-name-prefix: 配置线程名称前缀,默认为task-
  • pool.core-size: 配置线程池初始化时创建的线程个数
  • pool.max-size: 配置线程池最大线程数
  • pool.queue-capacity: 配置线程缓冲队列大小,如果缓冲队列达到了上限,Spring会将线程数增加,上限为pool.max-size
  • pool.keep-alive: 配置线程最大空闲时间,超过此时间,线程将会被回收

2.定时任务

在实际项目中往往还需要定时任务,比如定时清理日志、定时备份数据库中的数据、定时统计数据做报表等等。下面就来看一看SpringBoot的定时任务怎么用吧。

2.1 使用定时任务

只需要以下两个步骤,便可使用SpringBoot的定时任务:

  • 在启动类添加@EnableScheduling注解,开启注解使用定时任务的功能
  • 在要定时执行的方法前加上@Scheduled注解,同时需要将该方法所在类注入Spring IOC容器

启动类代码:

@SpringBootApplication
@EnableAsync
@EnableScheduling
public class SpringBootTaskApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootTaskApplication.class, args);
    }

}

定时任务代码如下:

@Service
public class ScheduledService {

    @Scheduled(cron = "*/1 * * * * *")
    public void tellTime()
    {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

        System.out.println("currentTime:" + simpleDateFormat.format(new Date()));
    }
}

上面这段代码1s执行一次,作用是打印当前时间。

2.2 cron表达式详解

格式:cron = " 秒 分 时 日 月 星期几 "

属性 取值范围 特殊符号
0-59 , - * /
0-59 , - * /
0-59 , - * /
1-31 , - * / ? L W C
1-12 , - * /
星期几 0 - 7(0、7都代表周日) , - * / ? L C #

特殊符号解释

符号 含义
, 以逗号分割指定多个值
- 区间
* 任意
/ 步长
? 日/星期冲突匹配。比如: * * * ? * 1 每周1执行,则日用 ? 不能用 * , 不是每一天都是周一; * * * 2 * ? 每月2号,则星期不能用*
L 最后
W 工作日
# 这个月的第几个星期几 如3#2代表这个月的第2个星期三

用法举例:

表达式 含义
*/1 * * * * * 每1s执行一次
* 1-5 * * * * 第1分钟到第5分钟触发,触发时每秒执行一次
0 1-5 * * * * 第1分钟到第5分钟的第0秒分别触发一次
0 */2 * * * * 每隔2分钟执行一次
0 0 13 * * * 每天13:00:00执行一次
* 1-5 * * * * 第1分钟到第5分钟触发,触发时一直执行
0 0-5 14 * * * 在每天下午2点到下午2:05期间的每1分钟触发一次
0 0 23 L * ? 每月最后一天23:00:00执行一次
0 30 17 LW * ? 每个月最后一个工作日的17:30:00触发任务一次

2.3 配置定时任务

SpringBoot在默认情况下使用一个线程来处理定时任务,其实这已经满足了绝大多数的需求。如果想要更改,可通过设置spring.task.scheduling.pool.size属性:

spring:
  task:
    scheduling:
      thread-name-prefix: my-scheduling-
      pool:
        size: 3

关于SpringBoot的异步任务、定时任务就讲解到这里,欢迎大家在评论区留言讨论。

发布了41 篇原创文章 · 获赞 18 · 访问量 1万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章