我一直在尝试使用Java 8 CompletableFutures。我的理解是,调用CompletableFuture.supplyAsync(供应商供应商,执行程序执行程序)将始终在传入的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来处理它们,我更好奇的是,它们是如何在主要部分执行某些任务的线程。
答案 0 :(得分:1)
打印&#34;进行繁重计算的任务&#34;使用thenApply
调用,这意味着您没有指定执行此任务的执行程序,系统可以自由使用任何执行程序,包括当前线程。
如果您希望此作业在预定义的执行程序上执行,请改为使用thenApplyAsync
,使用或不使用第二个参数 - executor。