【发布时间】:2016-03-29 10:24:25
【问题描述】:
我试图了解 Java 8 中的 CompletableFuture 如何与 Java memory model 交互。在我看来,为了程序员的理智,理想情况下,以下内容应该是正确的:
- 线程中完成
CompletableFuture的操作happen-before任何completions相关阶段都会被执行 - 线程中
注册完成的操作创建了一个依赖阶段发生之前completion依赖阶段被执行
java.util.concurrent documentation 中有一条注释说:
在将
Runnable提交给Executor之前,线程中的操作happen-before 开始执行。对于Callables 提交到ExecutorService也是如此。
这表明第一个属性为真,只要完成未来的线程执行 completion 依赖阶段或将其提交给Executor。另一方面,在阅读CompletableFuture documentation 之后,我不太确定:
为非异步方法的依赖完成提供的操作可以由完成当前
CompletableFuture的线程执行,或者由完成方法的任何其他调用者执行。
这让我想到了我的问题:
- 以上两个假设属性是真的还是假的?
- 在使用
CompletableFuture时,是否有任何关于内存可见性保证的特定文档?
附录:
以具体示例的方式,考虑以下代码:
List<String> list1 = new ArrayList<>();
list1.add("foo");
CompletableFuture<List<String>> future =
CompletableFuture.supplyAsync(() -> {
List<String> list2 = new ArrayList<>();
list2.addAll(list1);
return list2;
});
是否保证将 "foo" 添加到 list1 对 lambda 函数可见?是否保证将list1 添加到list2 对future 的依赖阶段可见?
【问题讨论】:
-
你能解释一下“注册完成的线程”是什么意思吗
-
@Misha: OP 显然意味着一个完成动作 或一个依赖阶段。
-
@Holger 如果他的意思是完成动作,那么这两个问题是相同的。他的意思是依赖阶段更合理。
-
@Misha:我的意思是“完成动作”,意思是“完成时要执行的动作”,即通过
thenRun提交。我承认这是模棱两可的,所以,既然所有的提交方法都会创建一个依赖阶段,那么这里应该首选术语“依赖阶段”。 -
@Misha @Holger 抱歉有任何歧义。 “完成”是指传递给
thenRun等的函数。“创建依赖阶段”和“执行依赖阶段”是这里的最佳术语吗?
标签: java java-8 java.util.concurrent java-memory-model completable-future