I have a question about thread management for the tomcat server and application. Here is a sample code:
@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;
}
Here, This is a simple API using spring boot. What I have done here?
getValueAsyncUsingCompletableFuture I am calling processRequest on CompletableFuture.supplyAsync(this::processRequest). So obviously it will run under separate thread.processRequest where only have a Thread.sleep for 10s.getValueAsyncUsingCompletableFuture is returning a completableFutureNow after calling the Endpoints from the browser its output is as expected. It waits 10 seconds and provides a response. The output log is given below.

Here,
nio-8080-exec-8 thread. It also showing request received and servlet thread released.processRequest. Here it is showing for CompletableFuture execution part. It is handling under onPool-worker-2 thread.Now, Here is my question:
processRequest method, is it released the tomcat allocated thread nio-8080-exec-8? I am telling based on the log. Is this thread released and go back to tomcat connection pool?completableFuture is done?Thanks in advance
Spring uses the ServletRequest#startAsync() method introduced in Servlet 3.0 (see Oracle's tutorial). This means that:
http-nio-8080-exec-8 is returned to its executor shortly after getValueAsyncUsingCompletableFuture is called, but the response is not yet committed to the client as in the synchronous case. Spring switches the ServletRequest into asynchronous mode whenever your handler returns a CompletionStage.getValueAsyncUsingCompletableFuture exits, the ServletRequest and ServletResponse can still be used to send data to the client. Spring appends a stage to your CompletableFuture, which writes the result to ServletResponse and ends the request using AsyncContext#complete(). This stage can be executed on any thread. In your case it executes on the ForkJoinPool since you launched the CompletableFuture using the default executor. However any executor would be fine.getValueAsyncUsingCompletableFuture (or more precisely DispatcherServlet#service). The rest of the allocations is up to you.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With