Spring及Springboot 异步请求

1.java 异步请求

Spring在3.2的版本上就已经为我们提供的相应的机制,以应对Http Nio的场景。

官方文档中说DeferredResult和Callable都是为了异步生成返回值提供基本的支持。

  •  *简单来说就是一个请求进来,如果你使用了DeferredResult或者Callable,在没有得到返回数据之前, DispatcherServlet和所有Filter就会退出Servlet容器线程,但响应保持打开状态, 一旦返回数据有了,这个DispatcherServlet就会被再次调用并且处理,以异步产生的方式,向请求端返回值。
    

2.异步请求实现方式

	1. Callable加SpringMvc 自带线程池,可以对SpringBoot 默认创建的ThreadPoolTaskExecutor 进行覆写,按照业务需求定义线程池
 /**
     * 1.使用 springboot 自动生成的ThreadPoolTaskExecutor 线程池
     * @param request
     * @param name
     * @return
     */
    @GetMapping("/test1")
    @ResponseBody
    public  Callable<String> test1(HttpServletRequest request,@RequestParam (required = true) String name){
        log.info("--------start-----");
        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                Thread.sleep(2000);
                log.info("当前线程名" + Thread.currentThread().getName());
                return "hello" + name + "访问 test1";
            }
        };
        log.info("--------end-----");
        return callable;
    }
  

## 覆写 mvc 线程池

  

```java
@Configuration
@ConfigurationProperties(prefix = "web-mvc-async")
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(2);
        t.setMaxPoolSize(3);
        t.setQueueCapacity(1024);
        t.setThreadNamePrefix("My-Mvc-Thread-");
        t.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); //在调用线程,即主线程执行
        return t;
    }
}

使用自定义线程池和Future 方式


private static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(cpuNum, cpuNum * 2, 0L,
            TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1024));

  /**
     * 使用配置bean 自定义线程池,返回submit.get() 要放到最后一行,不阻塞主线程
     * @param request
     * 
     * */
@GetMapping("/test2")
    @ResponseBody
    public  String test2(HttpServletRequest request,@RequestParam (required = true) String name)
            throws ExecutionException, InterruptedException {
        log.info("--------start2-----");
        Future<String> submit = threadPoolExecutor.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                Thread.sleep(2000);
                log.info("当前线程名" + Thread.currentThread().getName());
                return "hello" + name + "访问 test2";
            }
        });
        log.info("--------end2-----");
        return submit.get();
    }
对于没有返回值得任务来说可以使用自定义线程池,也可以使用@Async 异步注解
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值