目录

0. 摘要

1. Callable

1.1 使用方法

1.2 测试结果

​编辑

2. WebAsyncTask

2.1 使用方法

2.2 测试结果

3. DeferredResult

3.1 使用方法

3.2 测试结果

4. @Async

4.1 使用方法

4.2 测试结果


0. 摘要

SpringBoot Controller异步返回,避免主干线程阻塞,主要有三类方法,分别是 Callble、WebAsyncTask和DeferredResult, @Async测试异步执行后,结果无法返回

1. Callable

1.1 使用方法

    @RequestMapping("asyncCallable/{param}")
    public Callable<String> asyncCallable(@PathVariable("param") String param){

        log.info("asyncCallable controller start:{}", Thread.currentThread().getName());

        Callable<String> call = new Callable<String>() {
            @Override
            public String call() throws Exception {
                log.info("asyncCallable call start:{}", Thread.currentThread().getName());
                Thread.sleep(100000);
                log.info("asyncCallable call end:{}", Thread.currentThread().getName());
                return String.format("asynCallable %s:%s", param, new Date());
            }
        };
        log.info("asyncCallable controller end:{}", Thread.currentThread().getName());
        return call;
    }

异步响应,callable专用线程处理,主干线程不阻塞
 

1.2 测试结果

 

2. WebAsyncTask

2.1 使用方法

    @RequestMapping("asyncWebAsyncTask/{param}")
    public WebAsyncTask<String> asyncWebAsyncTask(@PathVariable("param") String param){
        log.info("asyncWebAsyncTask controller start:{}", Thread.currentThread().getName());

        WebAsyncTask<String> task = new WebAsyncTask<>(60 * 1000l, new Callable<String>() {
            @Override
            public String call() throws Exception {
                log.info("asyncWebAsyncTask call start:{}", Thread.currentThread().getName());
                Thread.sleep(30000);
                log.info("asyncWebAsyncTask call end:{}", Thread.currentThread().getName());
                return String.format("asynCallable %s:%s", param, new Date());
            }
        });

        task.onTimeout(new Callable<String>() {
            @Override
            public String call() throws Exception {
                log.warn(param +":timeOut");
                return param + ":timeOut";
            }
        });

        task.onCompletion(new Runnable() {
            @Override
            public void run() {
                log.info(param +":complete");
            }
        });

        log.info("asyncWebAsyncTask controller end:{}", Thread.currentThread().getName());
        return task;
    }

主干线程不阻塞,异步处理

2.2 测试结果

 

3. DeferredResult

3.1 使用方法

    @RequestMapping("deferredResult/{param}")
    public DeferredResult<String> deferredResult(@PathVariable("param") String param){

        log.info("deferredResult controller start:{}", Thread.currentThread().getName());

        DeferredResult<String> result = new DeferredResult<>();

        new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                log.info("deferredResult call start:{}", Thread.currentThread().getName());
                Thread.sleep(100000);
                result.setResult(param +":deferredResult");
                log.info("deferredResult call end:{}", Thread.currentThread().getName());
            }
        }).start();

        log.info("deferredResult controller end:{}", Thread.currentThread().getName());
        return result;
    }

3.2 测试结果

4. @Async

4.1 使用方法

    // controller method


    @Autowired
    AsyncService asyncService;

    @RequestMapping("async/{param}")
    public String async(@PathVariable("param") String param) throws InterruptedException {

        log.info("asyncService controller start:{}", Thread.currentThread().getName());
        String result = asyncService.asyncService(param);
        log.info("asyncService controller end:{}", Thread.currentThread().getName());
        return result;
    }

 @Asyn Service类

package com.example.springboottest.async;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;

@Slf4j
@Component
public class AsyncService {

    @Async
    public String asyncService(@PathVariable("param") String param) throws InterruptedException {

        log.info("asyncService call start:{}", Thread.currentThread().getName());
        Thread.sleep(10000);
        log.info("asyncService call end:{}", Thread.currentThread().getName());
        return param +":async";
    }
}

@Async 需要添加注解支持启用异步功能

package com.example.springboottest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

// main 入口添加@EnableAsync
@EnableAsync
@SpringBootApplication
public class SpringBootTestApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootTestApplication.class, args);
    }

}

4.2 测试结果

不等待@Async返回,直接返回结果,controller无法获取响应结果 

 

5. 完成controller类

package com.example.springboottest.async;


import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.context.request.async.WebAsyncTask;

import java.util.Date;
import java.util.concurrent.Callable;

@RestController
@RequestMapping("/async")
@Slf4j
public class AsyncController {

    @RequestMapping("asyncCallable/{param}")
    public Callable<String> asyncCallable(@PathVariable("param") String param){

        log.info("asyncCallable controller start:{}", Thread.currentThread().getName());

        Callable<String> call = new Callable<String>() {
            @Override
            public String call() throws Exception {
                log.info("asyncCallable call start:{}", Thread.currentThread().getName());
                Thread.sleep(100000);
                log.info("asyncCallable call end:{}", Thread.currentThread().getName());
                return String.format("asynCallable %s:%s", param, new Date());
            }
        };
        log.info("asyncCallable controller end:{}", Thread.currentThread().getName());
        return call;
    }


    @RequestMapping("asyncWebAsyncTask/{param}")
    public WebAsyncTask<String> asyncWebAsyncTask(@PathVariable("param") String param){
        log.info("asyncWebAsyncTask controller start:{}", Thread.currentThread().getName());

        WebAsyncTask<String> task = new WebAsyncTask<>(60 * 1000l, new Callable<String>() {
            @Override
            public String call() throws Exception {
                log.info("asyncWebAsyncTask call start:{}", Thread.currentThread().getName());
                Thread.sleep(30000);
                log.info("asyncWebAsyncTask call end:{}", Thread.currentThread().getName());
                return String.format("asynCallable %s:%s", param, new Date());
            }
        });

        task.onTimeout(new Callable<String>() {
            @Override
            public String call() throws Exception {
                log.warn(param +":timeOut");
                return param + ":timeOut";
            }
        });

        task.onCompletion(new Runnable() {
            @Override
            public void run() {
                log.info(param +":complete");
            }
        });

        log.info("asyncWebAsyncTask controller end:{}", Thread.currentThread().getName());
        return task;
    }

    @RequestMapping("deferredResult/{param}")
    public DeferredResult<String> deferredResult(@PathVariable("param") String param){

        log.info("deferredResult controller start:{}", Thread.currentThread().getName());

        DeferredResult<String> result = new DeferredResult<>();

        new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                log.info("deferredResult call start:{}", Thread.currentThread().getName());
                Thread.sleep(100000);
                result.setResult(param +":deferredResult");
                log.info("deferredResult call end:{}", Thread.currentThread().getName());
            }
        }).start();

        log.info("deferredResult controller end:{}", Thread.currentThread().getName());
        return result;
    }

    @Autowired
    AsyncService asyncService;

    @RequestMapping("async/{param}")
    public String async(@PathVariable("param") String param) throws InterruptedException {

        log.info("asyncService controller start:{}", Thread.currentThread().getName());
        String result = asyncService.asyncService(param);
        log.info("asyncService controller end:{}", Thread.currentThread().getName());
        return result;
    }


}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐