java异步处理耗时请求

模拟异步调用

import com.springdemo2.service.helloService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.Callable;

@RestController
public class HelloController2 {

    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);

    @Autowired
    private helloService hello;

    @GetMapping("/helloworld")
    public String helloWorldController() {
        logger.info(Thread.currentThread().getName() + " 进入helloWorldController方法");
        String say = hello.sayHello();
        logger.info("请求完成");
        return say;
    }

    /**
     * 异步调用restful
     * 当controller返回值是Callable的时候,springmvc就会启动一个线程将Callable交给TaskExecutor去处理
     * 然后DispatcherServlet还有所有的spring拦截器都退出主线程,然后把response保持打开的状态
     * 当Callable执行结束之后,springmvc就会重新启动分配一个request请求,然后DispatcherServlet就重新
     * 调用和处理Callable异步执行的返回结果, 然后返回视图
     *
     * @return
     */
    @GetMapping("/hello1")
    public Callable<String> helloController() {
        logger.info(Thread.currentThread().getName() + " 进入helloController方法");
        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                logger.info(Thread.currentThread().getName() + " 进入call方法");
                // 从这里写耗时任务的代码
                String say = hello.sayHello();
                //
                logger.info(Thread.currentThread().getName() + " 从helloService方法返回");
                return say;
            }
        };
        logger.info(Thread.currentThread().getName() + " 从helloController方法返回");
        return callable;
    }
}

模拟耗时请求

import org.springframework.stereotype.Component;

@Component
public class helloService {

   public String sayHello(){
       try {
           Thread.sleep(10000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       return "aa";
   }
}

日志

helloController调用新线程处理任务,而helloWorldController为当前线程处理,阻塞当前线程

2019-03-18 20:13:56.171  INFO 7495 --- [io-8080-exec-10] c.s.contorller.HelloController           : http-nio-8080-exec-10 进入helloController方法
2019-03-18 20:13:56.171  INFO 7495 --- [io-8080-exec-10] c.s.contorller.HelloController           : http-nio-8080-exec-10 从helloController方法返回
2019-03-18 20:13:56.172  INFO 7495 --- [         task-9] c.s.contorller.HelloController           : task-9 进入call方法
2019-03-18 20:13:57.222  INFO 7495 --- [nio-8080-exec-1] c.s.contorller.HelloController           : http-nio-8080-exec-1 进入helloController方法
2019-03-18 20:13:57.222  INFO 7495 --- [nio-8080-exec-1] c.s.contorller.HelloController           : http-nio-8080-exec-1 从helloController方法返回
2019-03-18 20:13:57.223  INFO 7495 --- [        task-10] c.s.contorller.HelloController           : task-10 进入call方法
2019-03-18 20:13:58.084  INFO 7495 --- [nio-8080-exec-2] c.s.contorller.HelloController           : http-nio-8080-exec-2 进入helloController方法
2019-03-18 20:13:58.084  INFO 7495 --- [nio-8080-exec-2] c.s.contorller.HelloController           : http-nio-8080-exec-2 从helloController方法返回
2019-03-18 20:13:58.084  INFO 7495 --- [        task-11] c.s.contorller.HelloController           : task-11 进入call方法
2019-03-18 20:14:06.176  INFO 7495 --- [         task-9] c.s.contorller.HelloController           : task-9 从helloService方法返回
2019-03-18 20:14:07.223  INFO 7495 --- [        task-10] c.s.contorller.HelloController           : task-10 从helloService方法返回
2019-03-18 20:14:08.087  INFO 7495 --- [        task-11] c.s.contorller.HelloController           : task-11 从helloService方法返回


2019-03-18 20:14:20.996  INFO 7495 --- [nio-8080-exec-7] c.s.contorller.HelloController           : http-nio-8080-exec-7 进入helloWorldController方法
2019-03-18 20:14:22.051  INFO 7495 --- [nio-8080-exec-8] c.s.contorller.HelloController           : http-nio-8080-exec-8 进入helloWorldController方法
2019-03-18 20:14:22.836  INFO 7495 --- [nio-8080-exec-9] c.s.contorller.HelloController           : http-nio-8080-exec-9 进入helloWorldController方法
2019-03-18 20:16:56.858  INFO 7499 --- [nio-8080-exec-1] c.s.contorller.HelloController           : http-nio-8080-exec-1请求完成
2019-03-18 20:16:57.424  INFO 7499 --- [nio-8080-exec-2] c.s.contorller.HelloController           : http-nio-8080-exec-2请求完成
2019-03-18 20:16:58.058  INFO 7499 --- [nio-8080-exec-3] c.s.contorller.HelloController           : http-nio-8080-exec-3请求完成

你可能感兴趣的:(java)