[英]CompletableFuture showing inconsistent threading behavior
CompletableFuture的文档为异步执行指定了以下行为:
所有没有显式Executor参数的异步方法都是使用ForkJoinPool#commonPool()执行的(除非它不支持并行度至少为2,在这种情况下,将创建一个新的Thread来运行每个任务)。 为了简化监视,调试和跟踪,所有生成的异步任务都是标记接口AsynchronousCompletionTask的实例。
但是,同步(或至少是非异步)方法的行为仍然不清楚。 在大多数情况下,代码使用原始线程执行,如下所示:
Thread thread = Thread.currentThread();
CompletableFuture.runAsync(() -> {
// Should run on the common pool - working as expected
assert thread != Thread.currentThread();
}).thenRun(() -> {
// Returns to running on the thread that launched.. sometimes?
assert thread == Thread.currentThread();
}).join();
但是,重复此测试会产生不一致的结果,因为第二个代码块有时会使用公共池。 在这种情况下的预期行为是什么?
看着在OpenJDK执行CompletableFuture后在这里 ,它闻起来像你遇到一种竞争状态。 假设我们正在执行类似runAsync(a).thenRun(b)
。 如果a
以前在公共池线程完成执行thenRun(b)
被称为当前线程上,然后b
立即在当前线程上运行一次thenRun(b)
终于被调用。 在另一方面,如果thenRun(b)
之前被调用a
其他线程上完成,那么b
是相同的线程上运行作为a
曾经a
终于完成。
有点像这样:
class CompletableFuture:
function runAsync(a):
function c():
run a
for each b in the handler stack:
run b
run c on a different thread
return future representing c
function thenRun(b):
if c is done:
run b
else:
put b in c's handler stack
显然, b
在运行c
的线程,如果thenRun
之前被调用a
结束。 否则, b
在当前线程中运行。
如果要在哪个线程运行什么方面获得更一致的行为,则应尝试使用CompletableFuture#thenRunAsync
,以确保处理程序在某些特定的执行程序池中执行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.