前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >@Async一个注解搞定异步编程

@Async一个注解搞定异步编程

作者头像
小四的技术之旅
发布2022-07-26 08:01:33
3000
发布2022-07-26 08:01:33
举报
文章被收录于专栏:小四的技术文章

前言

之前写了几篇关于异步编程的文章,FutureFutureTaskCompletableFuture,今天我们来说一下另外一个基于注解的异步编程利器@Async,使用它代码会更加的简洁,更加的规范,不过在使用它的时候也会配合Future接口,下面我们会详细的介绍!

Java并发编程异步操作Future和FutureTask

Java8异步利器CompletableFuture的骚操作

@Async解析

@Async可以使用在方法上面,也可以使用在类上面,如果在类上使用,那么整个类的所有方法都是异步的,@Async注解的value是设置线程池,如果不设置,那么就会使用默认的SimpleAsyncTaskExecutor线程池,不过在实际使用中,我们肯定不能使用默认的,应该自定义一个线程池。

代码语言:javascript
复制
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Async {
    String value() default "";
}

@EnableAsync解析

在SpringBoot中如果要使用@Async,那么需要在项目的启动类上加上@EnableAsync注解,加上@EnableAsync注解,在启动SpringBoot项目的时候它会做一些配置,因为@Async本身就是基于AOP来实现,所以在项目启动的时候会去读取注解的信息,然后做相应的配置,会在Spring Bean进行装配的时候配置,@Async就会在Bean的后置处理BeanPostProcessor做一些配置。

实战演练

一、加上@EnableAsync注解

代码语言:javascript
复制
@EnableAsync
@SpringBootApplication
public class SpringAsyncApplication {

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

}

配置线程池

在实际使用中,我们需要配置线程池,下面的线程池参数已经写死在代码里面,但是生产环境上,我们应该将其配置在统一配置中心中,如nacos,这样,我们就能根据实际情况对参数进行调整。

代码语言:javascript
复制
/**
 * 功能说明:Async线程池配置
 * <p>
 * Original @Author: steakliu-刘牌, 2022-06-26  11:37
 * <p>
 * Copyright (C)2020-2022  小四的技术之旅 All rights reserved.
 */
@Configuration
public class ThreadPoolConfiguration {

    @Bean
    public TaskExecutor taskExecutor(){
        /**
         * CPU核数
         */
        int processors = Runtime.getRuntime().availableProcessors();
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(processors * 2);
        threadPoolTaskExecutor.setMaxPoolSize(processors * 4);
        threadPoolTaskExecutor.setThreadNamePrefix("async-thread-");
        threadPoolTaskExecutor.setKeepAliveSeconds(60);
        return threadPoolTaskExecutor;
    }
}

Service

AsyncService包含了四个异步任务,task1,task2,task3,task4,值得注意的是,使用@Async的方法,其返回值要么为void, 要么为Future,如果为其他类型,那么返回的为空,因为任务是交给线程池,所以需要用Future来记录执行结果,下面使用了CompletableFuture

代码语言:javascript
复制
/**
 * 功能说明:
 * <p>
 * Original @Author: steakliu-刘牌, 2022-06-26  11:17
 * <p>
 * Copyright (C)2020-2022  小四的技术之旅 All rights reserved.
 */
@Service
@Slf4j
public class AsyncService {

    @Async("taskExecutor")
    public void task1() throws InterruptedException {
        Thread.sleep(2000);
        log.info("=====开始执行task1====={}", Thread.currentThread().getName());
    }

    @Async("taskExecutor")
    public CompletableFuture<String> task2() {
        log.info("=====开始执行task2====={}", Thread.currentThread().getName());
        return CompletableFuture.completedFuture("task2");
    }

    @Async("taskExecutor")
    public void task3() {
        log.info("=====开始执行task3====={}", Thread.currentThread().getName());
    }

    @Async("taskExecutor")
    public void task4() {
        log.info("=====开始执行task4====={}", Thread.currentThread().getName());
    }
}

Controller

代码语言:javascript
复制
/**
 * 功能说明:
 * <p>
 * Original @Author: steakliu-刘牌, 2022-06-26  11:25
 * <p>
 * Copyright (C)2020-2022  小四的技术之旅 All rights reserved.
 */
@RestController
@AllArgsConstructor
@Slf4j
public class AsyncController {

    final AsyncService asyncService;

    @GetMapping("/async")
    public String async() throws InterruptedException, ExecutionException {
        asyncService.task1();
        CompletableFuture<String> future = asyncService.task2();
        log.info("===task2 result=== {}",future.get());
        asyncService.task3();
        asyncService.task4();
        return "async";
    }
}

输出

从输出结果看出几个接口是异步执行的,并且task2返回了值,如果不使用Future作为方法的返回类型,那么将会返回null。

使用其他返回类型

代码语言:javascript
复制
public String task2(){
    log.info("=====开始执行task2====={}",Thread.currentThread().getName());
    return "task2";
}

总结

从上面我们可以看出使用@Async还是比较简单的,特别对于SpringBoot,只需要简单的注解就能完事,不过在使用的时候我们要根据实际情况去考虑该 怎么用,比如数据之间的依赖,返回类型等等。

❝今天的分享就到这里,感谢你的观看,我们下期见!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 刘牌 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • @Async解析
  • @EnableAsync解析
  • 实战演练
    • 一、加上@EnableAsync注解
      • 配置线程池
        • Service
          • Controller
            • 输出
              • 使用其他返回类型
              • 总结
              相关产品与服务
              微服务引擎 TSE
              微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档