使用spring boot和completablefuture编写异步rest api及其线程管理

mum43rcc  于 2021-10-10  发布在  Java
关注(0)|答案(1)|浏览(598)

我有一个关于tomcat服务器和应用程序的线程管理的问题。下面是一个示例代码:

@RequestMapping(path = "/asyncCompletable", method = RequestMethod.GET)
    public CompletableFuture<String> getValueAsyncUsingCompletableFuture() {

        logger.info("Request received");
        CompletableFuture<String> completableFuture
                = CompletableFuture.supplyAsync(this::processRequest);
        logger.info("Servlet thread released");
        return completableFuture;

    }

    private String processRequest() {
        Long delayTime = 10000L;
        logger.info("Start processing request");
        try {
            Thread.sleep(delayTime);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        logger.info("Completed processing request");
        return "Processing done after " + delayTime;
    }

这里,这是一个使用SpringBoot的简单api。我在这里做了什么?
简单端点是一个简单的get方法,它返回一个字符串作为响应。
方法 getValueAsyncUsingCompletableFuture 我打电话来 processRequest 在…上 CompletableFuture.supplyAsync(this::processRequest) . 显然,它将在单独的线程下运行。
方法 processRequest 哪里只有一个房间 Thread.sleep 10秒。
这两种方法都有一个入口和出口日志。
还有api getValueAsyncUsingCompletableFuture 正在返回一个 completableFuture 现在,从浏览器调用端点后,其输出与预期一致。它等待10秒并提供响应。下面给出了输出日志。

这里,
日志的第一行和第二行显示在下面 nio-8080-exec-8 线它还显示收到的请求和释放的servlet线程。
在方法的最后2行日志中 processRequest . 这是给你看的 CompletableFuture 执行部分。它正在处理中 onPool-worker-2 线
现在,我的问题是:
在执行 processRequest 方法,是否释放tomcat分配的线程 nio-8080-exec-8 ? 我是根据日志说的。是否释放该线程并返回tomcat连接池?
如果tomcat线程被释放,那么客户端在执行 completableFuture 完成了吗?
您能描述一下当请求到达tomcat服务器和spring应用程序时线程分配是如何发生的吗。
提前谢谢

6qftjkof

6qftjkof1#

spring使用 ServletRequest#startAsync() Servlet3.0中引入的方法(参见oracle教程)。这意味着:
雄猫线 http-nio-8080-exec-8 之后不久归还给执行人 getValueAsyncUsingCompletableFuture 调用,但响应尚未提交到客户端,如同步情况下。Spring开关 ServletRequest 每当处理程序返回 CompletionStage .
按照你的方法 getValueAsyncUsingCompletableFuture 出口,出口 ServletRequestServletResponse 仍然可以用于向客户端发送数据。Spring给你的生活增添了一个舞台 CompletableFuture ,它将结果写入 ServletResponse 并使用 AsyncContext#complete() . 这个阶段可以在任何线程上执行。在您的情况下,它在 ForkJoinPool 自从你启动了 CompletableFuture 使用默认执行器。但是任何遗嘱执行人都可以。
tomcat分配一个要执行的线程 getValueAsyncUsingCompletableFuture (或者更准确地说 DispatcherServlet#service ). 其余的分配由您决定。

相关问题