我试图了解Java 8中的CompletableFuture
如何与Java memory model进行交互。在我看来,对于程序员的理智,理想情况下应该成立:
CompletableFuture
的线程中的操作在任何java.util.concurrent documentation中有一条说明:
在
Runnable
提交Executor
之前,线程中的操作发生在执行开始之前。同样,Callable
提交给ExecutorService
。
这表明第一个属性为true,只要完成将来的线程执行 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
{/ 1}}?
答案 0 :(得分:3)
是的,你的两个假设都是正确的。原因是,*Async()
中的所有CompletableFuture
方法都将使用java.util.concurrent.Executor
进行异步调用。如果您没有提供,那么这将是common pool或为每个任务创建new thread的执行者(如果您将公共池的大小限制为0或1)或者用户提供的执行程序。
正如您已经发现的那样,Executor
的{{3}}说:
在将Runnable对象提交给Executor之前,线程中的操作发生在执行开始之前,可能是在另一个线程中。
因此,在您的示例中,保证"foo"
是lambda中list1
的一部分,list2
在后续阶段中可见。
这基本上由Executor
。