CompletableFuture,可变对象和内存可见性 [英] CompletableFuture, mutable objects and memory visibility
问题描述
我试图了解Java 8中的CompletableFuture
如何与 Java内存模型.在我看来,出于程序员的理智,以下理想情况下应该成立:
I'm trying to understand how CompletableFuture
in Java 8 interacts with the Java memory model. It seems to me that for programmer sanity, the following should ideally hold true:
- 完成
CompletableFuture
发生之前任何完成依赖阶段的线程中的动作被执行 -
注册完成的线程中的操作创建了一个依赖阶段 happen-before 执行了completion依赖阶段
- Actions in the thread that completes a
CompletableFuture
happen-before anycompletionsdependent stages are executed - Actions in the thread that
registers a completioncreates a dependent stage happen-before thecompletiondependent stage is executed
java.util.concurrent中有一条注释文档说:
在向Executor
happen-before 提交Runnable
之前,线程中的操作开始执行.对于提交给
ExecutorService
的Callable
类似.
Actions in a thread prior to the submission of a
Runnable
to anExecutor
happen-before its execution begins. Similarly forCallable
s submitted to anExecutorService
.
这将建议第一个属性为true,只要完成未来的线程执行 completion 依赖阶段或将其提交给Executor
.另一方面,在阅读 CompletableFuture文档之后,不太确定:
Which would suggest that the first property is true, as long as the thread that completes the future executes the completion dependent stage or submits it to an Executor
. On the other hand, after reading CompletableFuture documentation I'm not so sure about that:
为完成非同步方法的依赖完成而提供的操作可以由完成当前
CompletableFuture
的线程执行,也可以由完成方法的任何其他调用者执行.
Actions supplied for dependent completions of non-async methods may be performed by the thread that completes the current
CompletableFuture
, or by any other caller of a completion method.
哪个带给我我的问题:
- 以上两个假设性质是否正确?
- 在使用
CompletableFuture
时,是否有任何有关内存可见性保证的具体文档?
- Are the two hypothetical properties above true or not?
- Is there any specific documentation anywhere about the presence or lack of memory visibility guarantees when working with
CompletableFuture
?
附录:
以一个具体示例的方式,考虑以下代码:
In the way of a concrete example, consider this code:
List<String> list1 = new ArrayList<>();
list1.add("foo");
CompletableFuture<List<String>> future =
CompletableFuture.supplyAsync(() -> {
List<String> list2 = new ArrayList<>();
list2.addAll(list1);
return list2;
});
是否确保对lambda函数可见的将"foo"
添加到list1
?是否可以保证将list1
添加到list2
对于future
的相关阶段是可见的?
Is it guaranteed that adding "foo"
to list1
is visible to the lambda function? Is it guaranteed that adding list1
to list2
is visible to the dependent stages of future
?
推荐答案
-
是的,您的两个假设都是正确的.原因是,
CompletableFuture
中的所有*Async()
方法都将使用java.util.concurrent.Executor
进行异步调用.如果您不提供,则为公用池或创建Executor的av = f"rel =" nofollow>文档说:
Yes, both of your hypotheses are true. The reason is, that all of the
*Async()
methods inCompletableFuture
will use ajava.util.concurrent.Executor
to make the asynchronous call. If you don't provide one, this will either be the common pool or an Executor that creates a new thread for each task (in case you restrict the size of the common pool to 0 or 1) or a user-provided Executor. As you already found out, the documentation of theExecutor
says:
在将Runnable对象提交给Executor之前,在线程中执行的操作发生在开始执行之前,也许在另一个线程中.
Actions in a thread prior to submitting a Runnable object to an Executor happen-before its execution begins, perhaps in another thread.
因此,在您的示例中,可以确保"foo"
是lambda中list1
的一部分,并且list2
在后续阶段中可见.
So in your example, it is guaranteed that "foo"
is part of list1
in your lambda and that list2
is visible in subsequent stages.
Executor
的文档基本上涵盖了这一点.
This is basically covered by the documentation of Executor
.
这篇关于CompletableFuture,可变对象和内存可见性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!