CompletableFuture,可变对象和内存可见性 [英] CompletableFuture, mutable objects and memory visibility

查看:315
本文介绍了CompletableFuture,可变对象和内存可见性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解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:

  1. 完成CompletableFuture 发生之前任何完成依赖阶段的线程中的动作被执行
  2. 注册完成的线程中的操作创建了一个依赖阶段 happen-before 执行了 completion 依赖阶段
  1. Actions in the thread that completes a CompletableFuture happen-before any completions dependent stages are executed
  2. Actions in the thread that registers a completion creates a dependent stage happen-before the completion dependent stage is executed

java.util.concurrent中有一条注释文档说:

在向Executor happen-before 提交Runnable之前,线程中的

操作开始执行.对于提交给ExecutorServiceCallable类似.

Actions in a thread prior to the submission of a Runnable to an Executor happen-before its execution begins. Similarly for Callables submitted to an ExecutorService.

这将建议第一个属性为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.

哪个带给我我的问题:

  1. 以上两个假设性质是否正确?
  2. 在使用CompletableFuture时,是否有任何有关内存可见性保证的具体文档?
  1. Are the two hypothetical properties above true or not?
  2. 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?

推荐答案

  1. 是的,您的两个假设都是正确的.原因是,CompletableFuture中的所有*Async()方法都将使用java.util.concurrent.Executor进行异步调用.如果您不提供,则为公用池或创建Executor的av = f"rel =" nofollow>文档说:

  1. Yes, both of your hypotheses are true. The reason is, that all of the *Async() methods in CompletableFuture will use a java.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 the Executor 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆