欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Boot 使用WebAsyncTask异步返回结果

程序员文章站 2023-08-13 20:39:50
在spring boot中(spring mvc)下请求默认都是同步的,一个请求过去到结束都是由一个线程负责的,很多时候为了能够提高吞吐量,需要将一些操作异步化,除了一些耗...

在spring boot中(spring mvc)下请求默认都是同步的,一个请求过去到结束都是由一个线程负责的,很多时候为了能够提高吞吐量,需要将一些操作异步化,除了一些耗时的业务逻辑可以异步化,我们的查询接口也是可以做到异步执行。

一个请求到服务上,是用的web容器的线程接收的,比如线程http-nio-8084-exec-1

我们可以使用webasynctask将这个请求分发给一个新的线程去执行,http-nio-8084-exec-1可以去接收其他请求的处理。一旦webasynctask返回数据有了,就会被再次调用并且处理,以异步产生的方式,向请求端返回值。

示例代码如下:

@requestmapping(value="/login", method = requestmethod.get)
public webasynctask<modelandview> longtimetask(){
  system.out.println("/login被调用 thread id is : " + thread.currentthread().getname());
  callable<modelandview> callable = new callable<modelandview>() {
      public modelandview call() throws exception {
        thread.sleep(1000); /模拟长时间任务
        modelandview mav = new modelandview("login/index");
        system.out.println("执行成功 thread id is : " + thread.currentthread().getname());
        return mav;
      }
  };
  return new webasynctask<modelandview>(callable);
}

可以看到输出结果如下:

/login被调用 thread id is : http-nio-8084-exec-1

执行成功 thread id is : mvcasync1

在执行业务逻辑之前的线程和具体处理业务逻辑的线程不是同一个,达到了我们的目的。

然后我做了一个并发测试,发现不停的在创建mvcasync1这个线程,我就在想,难道没有用线程池?

通过阅读源码才发现果真如此,webasyncmanager是spring mvc管理async processing的中心类。

默认是使用simpleasynctaskexecutor,这个会为每次请求创建一个新的线程

private asynctaskexecutor taskexecutor = new simpleasynctaskexecutor(this.getclass().getsimplename());

如果说任务指定了executor,就用任务指定的,没有就用默认的simpleasynctaskexecutor

asynctaskexecutor executor = webasynctask.getexecutor();
if (executor != null) {
  this.taskexecutor = executor;
}

我们可以配置async 的线程池,不需要为每个任务单独指定

通过configurer.settaskexecutor(threadpooltaskexecutor());来指定

import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.scheduling.concurrent.threadpooltaskexecutor;
import org.springframework.web.context.request.async.timeoutcallableprocessinginterceptor;
import org.springframework.web.servlet.config.annotation.asyncsupportconfigurer;
import org.springframework.web.servlet.config.annotation.webmvcconfigurationsupport;
@configuration
public class webmvcconfig extends webmvcconfigurationsupport {
  @override
  public void configureasyncsupport(final asyncsupportconfigurer configurer) {
    configurer.setdefaulttimeout(60 * 1000l);
    configurer.registercallableinterceptors(timeoutinterceptor());
    configurer.settaskexecutor(threadpooltaskexecutor());
  }
  @bean
  public timeoutcallableprocessinginterceptor timeoutinterceptor() {
    return new timeoutcallableprocessinginterceptor();
  }
  @bean
  public threadpooltaskexecutor threadpooltaskexecutor() {
    threadpooltaskexecutor t = new threadpooltaskexecutor();
    t.setcorepoolsize(10);
    t.setmaxpoolsize(50);
    t.setthreadnameprefix("yjh");
    return t;
  }
}

配置完之后就可以看到输出的线程名称是yjh开头的了,而且也不会一直创建新的线程

可以看到输出结果如下:

/login被调用 thread id is : http-nio-8084-exec-1
执行成功 thread id is : yjh1

总结

以上所述是小编给大家介绍的spring boot 使用webasynctask异步返回结果,希望对大家有所帮助