Spring @Async使用

Stella981
• 阅读 880

@EnableAsync开启@Async注解功能

一、功能

@Async注解标记的方法可以使该方法异步的进行调用,如果在类上使用该注解,那么这个类的所有方法都会作为异步方法进行调用

注意点,Async注解是基于SpringAop进行实现的,所以在相同的一个类中,方法互相调用是不会起到异步执行的作用的,这里多说一句,任何使用spring aop代理实现的类,类内部方法调用代理肯定是不生效的

1、不需要返回值调用方式

@Component
public class MyTestService {

    @Async
    public void a() {
        System.out.println("a");
    }
    
}

2、指定使用线程池的调用方式,(如果这个线程池在spring容器中不存在则抛出bean找不到的异常)

@Component
public class MyTestService {

    @Async("myThreadPoolExecutor")
    public void a() {
        System.out.println("a");
    }
    
}

3、需要返回值的调用方式

@Component
public class MyTestService {

    @Async
    public Future<String> a() throws Exception {
        return new AsyncResult<String>("a");
    }

}

二、关于Async注解线程的使用情况

1、默认情况1

假设当前spring容器中没有任何自定义的线程池,Async注解也没有指定使用哪个线程池,那么默认使用org.springframework.core.task.SimpleAsyncTaskExecutor类,进行异步方法的调用,这个类本身内部并没有线程池的概念,既每次使用都会使用new Thread().start()的方式进行创建和执行。(如果频繁大量的创建线程必然会发生问题... ,实际情况肯定是需要使用线程池的)

2、默认情况2

假设当前spring容器中有自定义的线程池,那么它会使用当前容器中的线程池(注意这里指的有是说容器中只有1个线程池的情况,假如超过1个,那么还是按照默认情况1,进行执行)

3、指定默认使用的线程池,既没有在Async注解中指定使用哪个线程池,替代默认的线程使用规则

实现org.springframework.scheduling.annotation.AsyncConfigurer接口,下面代码是这个接口的描述

public interface AsyncConfigurer {

    /**
     * The {@link Executor} instance to be used when processing async
     * method invocations.
     */
    Executor getAsyncExecutor();

    /**
     * The {@link AsyncUncaughtExceptionHandler} instance to be used
     * when an exception is thrown during an asynchronous method execution
     * with {@code void} return type.
     */
    AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler();

}

第一个方法是获取执行调度的线程池(也就是指定Async注解使用的线程池)

第二个方法是,处理执行过程中发生的异常情况(这里所说的异常情况不包含线程池的rejectedExecution,而是你的业务方法自身抛出的异常)

下面是具体代码配置

@Configuration
public class AsyncPoolConfiguration implements AsyncConfigurer {
    
    @Autowired
    private AsyncTaskThreadPool asyncTaskThreadPool;

    @Override
    public Executor getAsyncExecutor() {
        return asyncTaskThreadPool;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }
}
点赞
收藏
评论区
推荐文章
郜小超 郜小超
3年前
用 async/await 来处理异步
一级标题昨天看了一篇vue的教程,作者用async/await来发送异步请求,从服务端获取数据,代码很简洁,同时async/await已经被标准化,是时候学习一下了。先说一下async的用法,它作为一个关键字放到函数前面,用于表示函数是一个异步函数,因为async就是异步的意思,异步函数也就意味着该函数的执行不会阻塞后面代码的执行。写一个async
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
你不可不知的JS面试题(第二期)
1、什么是继承?子类可以使用父类的所有功能,并且对功能进行扩展。新增方法改用方法(1)、ES6使用extends子类继承父类的方法。// 父类    class A        constructor(name)            this.name name;                getNa
Stella981 Stella981
3年前
Spring Boot使用@Async实现异步调用:自定义线程池
在之前的SpringBoot基础教程系列中,已经通过《SpringBoot中使用@Async实现异步调用》(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fblog.didispace.com%2Fspringbootasync%2F)一文介绍过如何使用@Async注解来实现异
Easter79 Easter79
3年前
Spring注解@Scheduled 多线程异步执行
一、前言:Spring定时任务@Schedule的使用方式,默认是单线程同步执行的,启动过程是一个单线程同步启动过程,一旦中途被阻塞,会导致整个启动过程阻塞,其余的定时任务都不会启动。二、@Schedule注解多线程的实现:多个定时任务的执行,通过使用@Async注解来实现多线程异步调用。@Scheduled(
Wesley13 Wesley13
3年前
Java中异步注解@Async的陷阱
  或许,你在Java后端添加异步过程时会这样处理,然后摇摇大摆、灰溜溜地闪,而实际的运行结果却并不是我们期望的那样。那么,现在就将试验结果记录如下,以便少走弯路。  (一)在Controller层的公开接口直接添加@Async注解  当前端调用该种接口时会立刻结束,意味着开始即结束,不会在乎该异步接口返回的数据,其实这种接口只适合前端下发命令,后续
Wesley13 Wesley13
3年前
C# 基于任务的异步模式的创建与使用的简单示例
对于窗体程序,使用基于任务的异步模式需要用到Task类,下面示例下非常简单的用法。1.创建一个拥有异步方法的类该类拥有一个异步方法DoSomthingAsync,根据微软建议的命名规则该方法要带Async后缀publicclassDog{publicTask
SpringBoot2.0笔记四
当搞全局捕获异常时可以使用到AOP技术,采用异常通知,也可以用AOP搞日志记录在类上面加上@EnableAsyns注解开启异步调用@Asyns,在方法上加上此注解,可以实现异步调用,底层是多线程技术,相当于加上这个注解的方法重新开启了一个单独的线程正常情况下,当A方法调用B方法时,是需要B方法执行完成,有返回结果时等待返回。这是顺序的方式从上到下执行程序,当使用@Asyns注解时,A方法调用B方法,不用等待B方法执行完成,可以直接向下执行,B方法单独开启一个线程,两个方法同时运行。@Va
Easter79 Easter79
3年前
SpringBoot2.0笔记四
当搞全局捕获异常时可以使用到AOP技术,采用异常通知,也可以用AOP搞日志记录在类上面加上@EnableAsyns注解开启异步调用@Asyns,在方法上加上此注解,可以实现异步调用,底层是多线程技术,相当于加上这个注解的方法重新开启了一个单独的线程正常情况下,当A方法调用B方法时,是需要B方法执行完成,有返回结果时等待返回。这是顺序的方式从上到下
京东云开发者 京东云开发者
11个月前
你真的了解@Async吗? | 京东云技术团队
开发中会碰到一些耗时较长或者不需要立即得到执行结果的逻辑,比如消息推送、商品同步等都可以使用异步方法,这时我们可以用到@Async。但是直接使用@Async会有风险,当我们没有指定线程池时,他会默认使用其Spring自带的SimpleAsyncTaskExecutor线程池,会不断的创建线程,当并发大的时候会严重影响性能。所以可以将异步指定线程池使用