为什么 CompletableFuture 的 thenAccept() 不在主线程上运行

2024-05-13

我在 CompletableFuture 的 SupplyAsync() 中处理长时间运行的操作,并将结果放入 thenAccept() 中。有时 thenAccept() 在主线程上执行,但有时它在工作线程上运行。但我只想在主线程上运行 thenAccept() 操作。这是示例代码。

private void test() {

    ExecutorService executorService = Executors.newSingleThreadExecutor();

    CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
        System.out.println("supplyAsync | I am running on : " + Thread.currentThread().getName());
        return "Hello world";
    }, executorService);

    CompletableFuture<Void> cf3 = cf1.thenAccept(s -> {
        System.out.print("thenAccept | I am running on : " + Thread.currentThread().getName());
        System.out.println(" | answer : " + s);
    });

    cf3.thenRun(() -> {
        System.out.println("thenRun | I am running on : " + Thread.currentThread().getName());
        System.out.println();
    });

}

public static void main(String[] args) {

    App app = new App();
    for(int i = 0; i < 3; i++){
        app.test();
    }
}

结果是:

supplyAsync | I am running on : pool-1-thread-1
thenAccept | I am running on : main | answer : Hello world
thenRun | I am running on : main

supplyAsync | I am running on : pool-2-thread-1
thenAccept | I am running on : main | answer : Hello world
thenRun | I am running on : main

supplyAsync | I am running on : pool-3-thread-1
thenAccept | I am running on : pool-3-thread-1 | answer : Hello world
thenRun | I am running on : pool-3-thread-1

我怎样才能解决这个问题 ?


看看JavaDoc完整的未来 https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html。有趣的部分是关于完成阶段政策。

在那里你会发现使用非异步方法会导致一种非此即彼的情况。如果您随后查看实现,您将看到 Java 运行时的非公共部分。有一些UNSAFE处理意味着可能会发生某种竞争条件。

我建议使用thenAcceptAsync() and thenRunAsync()变体并通过你的执行者服务两个调用的变量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 CompletableFuture 的 thenAccept() 不在主线程上运行 的相关文章

随机推荐