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

使用Java CompletableFuture方法时的同步行为,java,asynchronous,spring-boot,executorservice,completable-future,Java,Asynchronous,Spring Boot,Executorservice,Completable Future,我将Java的完全未来像这样应用到spring boot@服务中: @Service public class ProcessService { private static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(3); @Autowired ChangeHistoryService changeHistoryService; public Attribute proces

我将Java的完全未来像这样应用到spring boot
@服务中

@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;
    }

}
过程
方法称为
@RestController
中的方法:

@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
仅根据数据库的参数将一些数据保存到数据库中。 我有一个微服务,它向这个“/processAttribute”端点发出许多请求,并打印所有响应

当我在
logChanges
方法中设置断点时,微服务正在等待一些请求,但不是所有请求,这使我认为
ChangeHistoryService::logChanges
并不总是异步运行。如果我没有为
runAsync
提供ExecutorService,微服务会阻塞更多请求,但仍然不是所有请求。 据我所知,这是因为处理请求的方法和
logChanges
方法共享相同的线程池(ForkJoinPool?)。
无论如何,由于我有另一个ExecutorService,
logChanges
不应该独立运行吗?或者是关于IDE如何处理异步任务上的断点?我正在使用IntelliJ IDEA。

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

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


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

问题在于断点将挂起所有线程,而不仅仅是运行
logChanges
方法的线程。在Intellij IDEA中,我通过右键单击断点并选中“线程”复选框(而不是“全部”)来修复此问题:


你好,卡亚曼!从执行者的文档中。newFixedThreadPool:>“如果在所有线程都处于活动状态时提交其他任务,它们将在队列中等待,直到有线程可用。”我不明白为什么即使线程池已饱和,提交任务的线程仍会阻塞。任务应添加到队列中,提交者线程继续运行,并且当任务是可用线程时,任务将独立处理。如果我有一个小线程池,队列将继续增长,但不会阻塞提交者线程。这不是它应该是什么?代码高于实际代码吗?您没有做任何愚蠢的事情来阻止请求线程执行,是吗?我的实际代码,所以我认为我没有做任何愚蠢的事情来阻止请求线程执行您是否尝试在
logChanges()
上使用
@Async
?您如何确定它不是异步运行的?您将向服务器发送何种流量?