Abhishek Galoda
Abhishek Galoda

Reputation: 3054

Can CompletableFuture can be used to create non-blocking I/O calls?

I am using CompletableFuture to make a web service call:

CompletableFuture<List<ProductCatalog>> completeableFuture =
    CompletableFuture.supplyAsync(() -> restTemplate.getForEntity(serviceURL, Response.class))
                     .thenApply(responseEntity -> buildResponse(responseEntity.getBody()));

Using the above code, I can see that the JVM assigns a pool worker (onPool-worker-1) thread to call the web service, so it is working as intended:

2018-03-12 10:11:08.402  INFO 14726 --- [nio-9020-exec-1] c.a.m.service.products.config.LogAspect  : Entering in Method :  productsCatalogClass Name :  com.arrow.myarrow.service.products.controller.ProductsControllerArguments :  []Target class : com.arrow.myarrow.service.products.controller.ProductsController
2018-03-12 10:11:43.561  INFO 14726 --- [onPool-worker-1] c.a.m.s.p.s.ProductsCatalogService       : listProductCatalog has top level elements - 8

Since the web service call can be time consuming, I am using the CompletableFuture.supplyAsync method to invoke the web service. Can someone answer the following questions:

I am running my application as a Spring Boot application on Tomcat. The main inspiration behind using CompletableFuture is that when the web service (a third-party system) is down, all my incoming requests won't get blocked. As Tomcat by default has a thread pool of size 200, will the system be blocked if 200 users are waiting for a response from the above call, or will there be any difference from using the above code?

Upvotes: 4

Views: 3012

Answers (1)

Kayaman
Kayaman

Reputation: 73558

That's not non-blocking I/O. It's just regular blocking I/O done in a separate thread. What's worse is if you don't explicitly provide an executor, the CompletableFutures will be executed in the common ForkJoinPool which will fill up quickly.

If you use an asynchronous servlet and a separate executor, you can have long running operations without using threads from Tomcat's worker pool. However this is only useful if the other requests can finish in some way. If all requests are offloaded to the custom executor, you'll just be switching one pool for another.

Upvotes: 5

Related Questions