繁体   English   中英

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

[英]Synchronous behavior when use methods of Java CompletableFuture

我正在像这样在Java Boot的@Service使用Java的CompletableFuture:

@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内部的方法称为process方法:

@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。

问题在于断点会挂起所有线程,而不仅是运行logChanges方法的线程。 我通过在断点上单击鼠标右键,然后选中“线程”复选框,而不是“全部”,来解决此问题:

在此处输入图片说明

您的线程池非常小,因此可以饱和它也就不足为奇了。 处理请求的线程与处理CompletableFutures的线程不同。 一个是服务器的内部组件,第二个是您显式创建的组件EXECUTOR

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM