我正在使用CompletableFuture
拨打网络服务电话:
CompletableFuture<List<ProductCatalog>> completeableFuture =
CompletableFuture.supplyAsync(() -> restTemplate.getForEntity(serviceURL, Response.class))
.thenApply(responseEntity -> buildResponse(responseEntity.getBody()));
使用上面的代码,我可以看到JVM分配了一个池工作者(onPool-worker-1
)线程来调用Web服务,因此它按预期工作:
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
由于Web服务调用可能非常耗时,因此我使用CompletableFuture.supplyAsync
方法来调用Web服务。有人可以回答以下问题:
我在Tomcat上运行我的应用程序作为Spring Boot应用程序。使用CompletableFuture
背后的主要灵感是当Web服务(第三方系统)关闭时,我的所有传入请求都不会被阻止。由于默认情况下Tomcat有一个大小为200的线程池,如果200个用户正在等待上述调用的响应,系统是否会被阻止,或者与使用上述代码有什么不同?
答案 0 :(得分:4)
这不是非阻塞I / O.它只是在一个单独的线程中定期阻塞I / O.更糟糕的是,如果您没有明确提供执行者,CompletableFutures
将在公共ForkJoinPool
中执行,这将很快填满。
如果使用asynchronous servlet和单独的执行程序,则可以在不使用Tomcat工作池的线程的情况下长时间运行操作。但是,这仅在其他请求可以某种方式完成时才有用。如果所有请求都被卸载到自定义执行程序,那么您只需将一个池切换为另一个池。