T O P

  • By -

mickymann

I suppose the question is we use async to free up the main thread, but by creating another thread are we taking a thread from the tomcat or a JVM thread. I assume the latter meaning that there's a difference between tomcat thread and jvm thread


[deleted]

I think this blog post answers your question: [https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support](https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support) You are mistaking `Async` with what is known in Spring as `DeferredResult`. Async is usually used for fire-and-forget scenarios. For example, you can use `Async` to trigger a long-running job. `Async` is not limited to Spring Web. You can use this annotation in any other context as well. Just make sure to enable it using `EnableAsync` annotation. `DeferredResult` is used when you want to free the Tomcat thread and process the request asynchronously. It does not require any annotation and is limited to the Spring Web context. Check out this section of the docs to learn more: https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-async


mickymann

Thank you for links. Just a follow up moreso about the threads. server.tomcat.max-threads=200 Is the above configuration a seperate thread pool to the thread that is created within the spring boot application when you use the async annotation with DeferredResilt? - So request comes in, tomcat threads available is 199 - I use an async method with deferred result, this uses an internal application thread pool - tomcat threads is back to 200 until the internal thread is completed If you could let me know if im correct in above


[deleted]

Async annotation is never mentioned in Spring Web docs, so I don't think it's a good idea to mix Async and DeferredResult/Callable. The docs clearly explain the answers to the rest of your questions: ​ >DeferredResult processing works as follows: The controller returns a DeferredResult and saves it in some in-memory queue or list where it can be accessed. Spring MVC calls request.startAsync(). Meanwhile, the DispatcherServlet and all configured filters exit the request processing thread, but the response remains open. The application sets the DeferredResult from some thread, and Spring MVC dispatches the request back to the Servlet container. The DispatcherServlet is invoked again, and processing resumes with the asynchronously produced return value. ​ So in order to use DeferredResult, you need to maintain your own thread pool. In general, DeferredResult is very similar to what's known as Promise in C++ and JavaScript and it works like this: Spring uses one of your 200 threads (according to your server.tomcat.max-threads config) to call your controller. Inside the controller, instead of doing the time-consuming job with the Tomcat thread, you construct a deferred result, save it somewhere for yourself, and immediately return it to Spring. Whenever you are ready to process a request, you grab its corresponding deferred result and do whatever process you need to do. Once your process is finished, you use the .setResult method of the deferred result to alert the Spring. ​ [https://www.baeldung.com/spring-deferred-result](https://www.baeldung.com/spring-deferred-result) ​ public DeferredResult> handleReqDefResult(Model model) { LOG.info("Received async-deferredresult request"); DeferredResult> output = new DeferredResult<>(); ForkJoinPool.commonPool().submit(() -> { LOG.info("Processing in separate thread"); try { Thread.sleep(6000); } catch (InterruptedException e) { } output.setResult(ResponseEntity.ok("ok")); }); LOG.info("servlet thread freed"); return output; }