CompletableFuture supplyAsync 有时会在主线程上运行

3

我一直在尝试Java 8的CompletableFuture。我的理解是,调用CompletableFuture.supplyAsync(Supplier supplier, Executor executor)总是会在由传入的Executor提供的线程中运行作业,但我注意到当我传递给它的供应商相当“简单”时,它有时会在主线程上运行。我的测试代码如下:

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class SyncTest {

    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(5);

        CompletableFuture<?>[] cfs = new CompletableFuture<?>[10];
        AtomicInteger mainCount = new AtomicInteger();
        for (int i = 0; i < cfs.length; i++) {
            int index = i;
            CompletableFuture<Integer> cf = 
CompletableFuture.supplyAsync(() -> {
                return index;
            }, pool).thenApply(j -> {
                if (Thread.currentThread().getName().equals("main")) {    
                    mainCount.incrementAndGet();
                }

                System.out.println(Thread.currentThread().getName() + ": " + index + ": doing a heavy computation");
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return j;
            });
            cfs[i] = cf;
        }

        System.out.println(Thread.currentThread().getName() + " doing other stuff");
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        CompletableFuture.allOf(cfs).join();
        pool.shutdown();
        System.out.println("Jobs on main: " + mainCount.get());
    }
}

我得到的输出大致如下:
main: 0: doing a heavy computation
main: 1: doing a heavy computation
pool-1-thread-3: 2: doing a heavy computation
pool-1-thread-4: 3: doing a heavy computation
main: 4: doing a heavy computation
main doing other stuff
pool-1-thread-4: 9: doing a heavy computation
pool-1-thread-5: 8: doing a heavy computation
pool-1-thread-2: 7: doing a heavy computation
pool-1-thread-1: 6: doing a heavy computation
pool-1-thread-3: 5: doing a heavy computation
Jobs on main: 3

我理解这只是一个相对简单的例子,而且还有其他针对CompletableFutures的方法,例如thenSupplyAsync和completedFuture,可用于处理它们。我更加好奇的是,如何可能在主线程上执行一些任务。


请检查此问题的答案:https://dev59.com/TV4c5IYBdhLWcg3wnrf9 - Ivan
可能是CompletableFuture,supplyAsync()和thenApply()的重复问题。 - Didier L
1个回答

3

打印“执行重算”任务使用thenApply调用,这意味着您没有指定执行此任务的执行程序,系统可以使用任何执行程序,包括当前线程。

如果您想要此作业在预定义执行程序上执行,请改用带或不带第二个参数 - 执行程序的thenApplyAsync


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接