使用Java CompletableFuture方法时的同步行为

时间:2018-01-15 12:39:26

标签: java asynchronous spring-boot executorservice completable-future

我正在使用Java的CompletableFuture这样的弹簧启动background-repeat: round

<defs>
    <pattern id="myPattern" width="200" height="100" patternUnits="userSpaceOnUse">
        ... some pattern ...
    </pattern>
</defs>

<rect width="200" height="230" fill="#myPattern"/>

@Service

中的方法调用@Service public class ProcessService { private static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(3); @Autowired ChangeHistoryService changeHistoryService; public Attribute process(Attribute attribute) { //some code CompletableFuture.runAsync(() -> changeHistoryService.logChanges(attribute), EXECUTOR); return attribute; } } 方法
process

@RestController仅根据参数将一些数据保存到数据库。 我有一个微服务,向这个“/ processAttribute”端点发出一些请求并打印所有响应。

当我在@RestController public class ProcessController { @Autowired ProcessService processService; @RequestMapping(value = "/processAttribute", method = {RequestMethod.POST}, produces = {MediaType.APPLICATION_JSON_VALUE}, consumes = {MediaType.APPLICATION_JSON_VALUE}) public Attribute applyRules(@RequestBody Attribute attribute) { Attribute resultValue = processService.service(attribute); return resultValue; } } 方法中放置一个断点时,微服务正在等待某个请求但不是所有这些让我认为ChangeHistoryService::logChanges并不总是运行异步。如果我不向logChanges提供ExecutorService,那么微服务会阻止更多请求,但仍然不是全部。 据我所知,这是因为处理请求的方法和ChangeHistoryService::logChanges方法共享相同的线程池(ForkJoinPool?)。 无论如何,因为我有另一个ExecutorService,runAsync不应该独立运行?或者是IDE如何处理异步任务中的断点?我正在使用IntelliJ IDEA。

2 个答案:

答案 0 :(得分:2)

问题是断点暂停所有线程,而不仅仅是运行logChanges方法的线程。我在Intellij IDEA中通过右键单击断点并选中“Thread”复选框来修复此问题,而不是“All”:

enter image description here

答案 1 :(得分:0)

你有一个相当小的线程池,所以难怪你可以让它饱和。处理请求的线程与处理CompletableFutures的线程不同。一个是服务器的内部组件,第二个是您明确创建的组件EXECUTOR

如果要增加异步性,请尝试给EXECUTOR更多线程,并查看行为如何相应地更改。目前EXECUTOR是一个瓶颈,因为有更多的线程可用于运行请求。

请注意,通过在logChanges()中放置一个断点,您将阻塞池中的一个线程,使其更加饱和。