@Async使用方法

157 阅读2分钟

电子合同第一期的时候,按照业务划分了流程,实现了电子合同的审批和签章。后续小需求迭代的同时开始优化代码,其中包含一些TP999较高的接口,分析发现这些接口中包含多个RPC调用,并且这些程序调用为同步调用,所以总耗时就较长,然而通过业务分析,这些RPC调用并无严格的先后关系,并且主流程与这些业务代码也并非强依赖,所以考虑将这些操作调用改为异步调用。

thrift异步调用配置?

什么叫异步

同步:按照代码顺序执行,执行下个代码需要等上个程序代码的结果的调用方式叫同步调用

异步:无需等待上个结果的返回即可执行的下段代码的调用方式叫异步调用

@Async的使用方法

方法一:注解方式

如果是spring boot项目,则只需要配置@EnableAsync注解即可。

如果是单纯的spring项目,则需先编写配置类实现AsyncConfiguer接口,实现其方法。

  • 异步线程的执行者,在里面配置自动执行的东西,比如线程池参数
  • 线程异常处理

代码块

package ds.watsons.app.label.config;
import java.util.concurrent.Executor;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configurable
@EnableAsync
public class TreadPoolConfigTest implements AsyncConfigurer{
    @Override
    public Executor getAsyncExecutor() {
        // TODO Auto-generated method stub
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //核心线程池数量,方法: 返回可用处理器的Java虚拟机的数量。
        executor.setCorePoolSize(Runtime.getRuntime().availableProcessors());
        //最大线程数量
        executor.setMaxPoolSize(Runtime.getRuntime().availableProcessors()*5);
        //线程池的队列容量
        executor.setQueueCapacity(Runtime.getRuntime().availableProcessors()*2);
        //线程名称的前缀
        executor.setThreadNamePrefix("this-excutor-");
        // setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务
        // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
        //executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
    /*异步任务中异常处理*/
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        // TODO Auto-generated method stub
        return new SimpleAsyncUncaughtExceptionHandler();
    }       
}

然后,再在方法上使用@Async注解,并且异步方法需要与其调用方法分别在两个类中,以保证spring的@Async注解有效。

方法二:xml配置方式

代码块

<task:annotation-driven executor="asyncExecutor" />
<!-- 线程池执行器-负责异步回调 -->
<task:executor id="asyncExecutor" pool-size="10-50" keep-alive="300"
                   queue-capacity="10" rejection-policy="ABORT"/>

异步方法的返回值

image.png

异步方法要么没有返回值,要么是Future

image.png

JDK8推出了CompletableFuture类来替代Future,采用了观察者模式,具体用法可参考colobu.com/2016/02/29/…

异步中的异常处理

异步中的事务

blog.didispace.com/springboota…

docs.spring.io/spring-fram…

blog.csdn.net/blueheart20…

colobu.com/2016/02/29/…