gpt4 book ai didi

java - 用于 Java CompletableFuture 组合的线程?

转载 作者:行者123 更新时间:2023-12-03 14:21:00 24 4
gpt4 key购买 nike

我开始适应 Java CompletableFuture组合,使用过 JavaScript promise 。基本上,组合只是在指定的执行器上安排了链式命令。但是我不确定在执行组合时哪个线程正在运行。
假设我有两个执行者,executor1executor2 ;为简单起见,假设它们是单独的线程池。我安排了一个 CompletableFuture (使用非常松散的描述):

CompletableFuture<Foo> futureFoo = CompletableFuture.supplyAsync(this::getFoo, executor1);
然后完成后我转换 FooBar使用第二个执行器:
CompletableFuture<Bar> futureBar .thenApplyAsync(this::fooToBar, executor2);
我明白 getFoo()将从 executor1 中的线程调用线程池。我明白 fooToBar()将从 executor2 中的线程调用线程池。
但是实际组合使用的是什么线程,即在 getFoo() 之后饰面和 futureFoo()已完成;但之前fooToBar()命令被安排在 executor2 ? 换句话说,哪个线程实际运行代码以在第二个执行器上调度第二个命令?
调度是否作为 executor1 中同一线程的一部分执行那个叫 getFoo() ?如果是这样,这个可完成的 future 组合是否等同于我简单的日程安排 fooToBar()executor1 的第一个命令中手动我自己任务?

最佳答案

这是故意未指定的。实际上,当没有 Async 的变体时,它将由同样处理链式操作的代码处理。后缀被调用并表现出类似的行为。
所以当我们使用下面的测试代码

CompletableFuture.supplyAsync(() -> {
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
return "";
}, r -> new Thread(r, "A").start())
.thenAcceptAsync(s -> {}, r -> {
System.out.println("scheduled by " + Thread.currentThread());
new Thread(r, "B").start();
});
它可能会打印
scheduled by Thread[A,5,main]
因为完成前一阶段的线程用于调度依赖操作。
但是当我们使用
CompletableFuture<String> first = CompletableFuture.supplyAsync(() -> "",
r -> new Thread(r, "A").start());
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
first.thenAcceptAsync(s -> {}, r -> {
System.out.println("scheduled by " + Thread.currentThread());
new Thread(r, "B").start();
});
它可能会打印
scheduled by Thread[main,5,main]
当主线程调用 thenAcceptAsync 时,第一个 future 已经完成,主线程将自行调度操作。
但这并不是故事的结局。当我们使用
CompletableFuture<String> first = CompletableFuture.supplyAsync(() -> {
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(5));
return "";
}, r -> new Thread(r, "A").start());

Set<String> s = ConcurrentHashMap.newKeySet();
Runnable submitter = () -> {
String n = Thread.currentThread().getName();
do {
for(int i = 0; i < 1000; i++)
first.thenAcceptAsync(x -> s.add(n+" "+Thread.currentThread().getName()),
Runnable::run);
} while(!first.isDone());
};
Thread b = new Thread(submitter, "B");
Thread c = new Thread(submitter, "C");
b.start();
c.start();
b.join();
c.join();
System.out.println(s);
它可能不仅打印组合 B AC A从第一个场景和 B BC C从第二。在我的机器上,它也可重复打印组合 B CC B表示一个 Action 传递给 thenAcceptAsync一个线程被另一个线程调用 thenAcceptAsync 提交给执行程序同时进行不同的 Action 。
这与评估传递给 thenApply 的函数的线程的场景相匹配(没有 Async )在 this answer 中描述.正如开头所说,这正是我所期望的,因为这两件事很可能由相同的代码处理。但与评估传递给 thenApply 的函数的线程不同,调用 execute 的线程 Executor上的方法文档中甚至没有提到。所以理论上,另一个实现可以使用一个完全不同的线程,既不调用 future 的方法也不完成它。

关于java - 用于 Java CompletableFuture 组合的线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66495718/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com