@Async实现异步

配置异步

1、使用默认线程池

  • 在springbootApplication启动类添加@EnableAsync注解
  • 在对应方法上添加@Async即可

2、使用自定义线程池

  • 在配置线程池的config类上添加@EnableAsync注解、@Configuration(value = "threadPool")
  • 在对应方法上添加@Async(value = "threadPool")在value属性上添加对应线程池的名称

注意

@Transactional和@Async注解的实现都是基于spring的AOP,AOP的实现基于动态代理模式。所以需要添加@Configuration注解将其交给springIOC容器管理



深入探讨

被@Async注解修饰的方法,返回值只能是void或者future

  • 因为底层线程池只支持这两种类型的返回,executor.submit(task)  =====>  return new Future<>();executor.execute(task) =====>  void
  • 需要有返回值的时候、需要用AsyncResult对象包装一下
@Async
public Future<String> asyncSay(){
    ***
    return new AsyncResult<>("hshuo");
}


//调用
Future<String> future = this.asyncSay();
future.get();

源码

类型不是future、不做处理直接扔掉返回null
if(result instanceof Future){
    return ((Future<?>)result).get();
}
return null;

都会以方法为维度,在map中维护方法和线程池的映射关系
private final Map<Method, AsyncTaskExecutor> executors = new ConcurrentHashMap(16);


注意事项

l  使用@Async会对@Transactional注解失效,如何生效: B方法上面使用了@Async注解,B中调用了CDC/D分别使用@Transactional做了标注,则可实现事务控制的目的。

l  由于注解是通过代理实现的,调用异步方法的、异步方法不在同一个类上,因为需要托管给IOC容器,才能找到代理类。

l  静态方法上的@Async失效

@Async注解的方法会在一个单独的线程内运行,不会被全局异常处理器捕获,需要自己设置异常处理。


hshuo的面试之路 文章被收录于专栏

作者目标是找到一份Java后端方向的工作 此专栏用来记录从Bilibili、书本、其他优质博客上面学习的内容 用于巩固、总结内容 主要包含Docker、Dubbo、Java基础、JUC、Maven、MySQL、Redis、SpringBoot、SpringCloud、数据结构、杂文、算法、计算机网络、操作系统、设计模式等相关内容

全部评论

相关推荐

02-11 17:47
已编辑
门头沟学院 Java
神哥不得了:神哥来啦~建议先在网上找一些高频的八股去背,然后再去广泛的背八股,这样的学习会更有效率一些,简历的这两个项目建议换掉,换成两个高质量的项目,这样的话获得面试的比例会更高一点,专业技能的话排版要注意一下,要加句号的话就都加,要不加就都不加,荣誉奖项的话写在教育经历里边吧,这个确实没有太多的含金量
点赞 评论 收藏
分享
评论
2
2
分享

创作者周榜

更多
牛客网
牛客企业服务