Spring中使用@Async来实现异步调用

2022-06-17 08:48:47

Spring中使用@Async来实现异步调用

1.关于异步调用

  • 同步就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果。
  • 异步调用则是只是发送了调用的指令,调用者无需等待被调用的方法完全执行完毕;而是继续执行下面的流程。
  • 在Spring中,基于@Async标注的方法,称之为异步方法;这些方法将在执行的时候,将会在独立的线程中被执行,调用者无需等待它的完成,即可继续其他的操作。

2.@Async的使用

开启@Async

  • 使用@EnableAsync注解可以在项目中开启@Async。

具体使用@Async

有两种方式来使用,可以选择有返回值和无返回值。

  • 无返回值
@AsyncpublicvoidreturnWithVoid(){}
  • 有返回值
@AsyncpublicFuture<String>returnWithString(){return"hello world";}

可以看到,这里使用@Async时没有设置参数,默认情况下,Spring使用SimpleAsyncTaskExecutor去执行这些异步方法(此执行器没有限制线程数)。我们也可以自定义线程池, 在不同的异步调用间做到资源隔离

3.线程池的配置

一个项目不推荐配置一个线程池,这样若是某些业务出现异常时,会影响到整个项目的健壮性。故根据业务,为不同的业务配置不同参数的数据库连接池。

importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;importjava.util.concurrent.Executor;importjava.util.concurrent.ThreadPoolExecutor;@ConfigurationpublicclassExecutorConfig{/**
   * 核心线程数:线程池创建时候初始化的线程数
   */@Value("${async-executor.core.pool.size}")privateint asyncCorePoolSize;/**
   * 最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
   */@Value("${async-executor.max.pool.size}")privateint asyncMaxPoolSize;/**
   * 缓冲队列200:用来缓冲执行任务的队列
   */@Value("${async-executor.queue.capacity}")privateint asyncQueueCapacity;/**
   * 允许线程的空闲时间(单位:秒):当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
   */@Value("${async-executor.keepalive.Seconds}")privateint asyncKeepAliveSeconds;/**
   * 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
   */@Value("${async-executor.thread.name.prefix}")privateString asyncThreadNamePrefix;@BeanpublicExecutorasyncServiceExecutor(){ThreadPoolTaskExecutor threadPoolTaskExecutor=newVisiableThreadPoolTaskExecutor();
    threadPoolTaskExecutor.setCorePoolSize(asyncCorePoolSize);
    threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
    threadPoolTaskExecutor.setMaxPoolSize(asyncMaxPoolSize);
    threadPoolTaskExecutor.setQueueCapacity(asyncQueueCapacity);
    threadPoolTaskExecutor.setKeepAliveSeconds(asyncKeepAliveSeconds);
    threadPoolTaskExecutor.setThreadNamePrefix(asyncThreadNamePrefix);//拒绝策略
    threadPoolTaskExecutor.setRejectedExecutionHandler(newThreadPoolExecutor.AbortPolicy());
    threadPoolTaskExecutor.initialize();return threadPoolTaskExecutor;}}

我们可以 @Async(“asyncServiceExecutor”) 以这样的方式来指明线程池进行异步调用。

  • 作者:过河的小卒子
  • 原文链接:https://blog.csdn.net/TP89757/article/details/108978004
    更新时间:2022-06-17 08:48:47