valores una tuplas tipos strings son signo significa que principio palabras objetos números mutables mutabilidad los lista linguistico las inmutables inmutable inmutabilidad filosofia ejemplos datos java java-8 java.util.concurrent java-memory-model completable-future

java - una - tipos mutables python



CompletableFutura, objetos mutables y visibilidad de memoria. (1)

Estoy tratando de entender cómo CompletableFuture en Java 8 interactúa con el modelo de memoria de Java . Me parece que para la salud mental del programador, lo siguiente debería ser ideal:

  1. Acciones en el hilo que completa un CompletableFuture antes de que se ejecuten las etapas dependientes de completaciones
  2. Las acciones en el hilo que registra una finalización crean una etapa dependiente antes de que se ejecute la etapa dependiente de finalización

Hay una nota en la documentación de java.util.concurrent que dice que:

Acciones en un hilo antes del envío de un Runnable a un Executor antes de que comience su ejecución. Del mismo modo para Callable s enviado a un ExecutorService .

Lo que sugeriría que la primera propiedad es verdadera, siempre que el hilo que completa el futuro ejecute la etapa dependiente de la finalización o la envíe a un Executor . Por otro lado, después de leer la documentación de CompletableFuture, no estoy tan seguro de eso:

Las acciones suministradas para completaciones dependientes de métodos no asíncronos pueden ser realizadas por el hilo que completa el CompletableFuture actual, o por cualquier otro llamador de un método de finalización.

Lo que me lleva a mis preguntas:

  1. ¿Son las dos propiedades hipotéticas anteriores verdaderas o no?
  2. ¿Existe alguna documentación específica sobre la presencia o la falta de garantías de visibilidad de la memoria cuando se trabaja con CompletableFuture ?

Apéndice:

En el camino de un ejemplo concreto, considere este código:

List<String> list1 = new ArrayList<>(); list1.add("foo"); CompletableFuture<List<String>> future = CompletableFuture.supplyAsync(() -> { List<String> list2 = new ArrayList<>(); list2.addAll(list1); return list2; });

¿Se garantiza que agregar "foo" a la list1 sea ​​visible para la función lambda? ¿Se garantiza que agregar list1 a list2 sea ​​visible para las etapas dependientes del future ?


  1. Sí, ambas hipótesis son ciertas. El motivo es que todos los métodos *Async() en CompletableFuture utilizarán un java.util.concurrent.Executor para realizar la llamada asíncrona. Si no proporciona uno, este será el grupo común o un Ejecutor que crea un nuevo hilo para cada tarea (en caso de que restrinja el tamaño del grupo común a 0 o 1) o un Ejecutor proporcionado por el usuario. Como ya descubrió, la documentation del Executor dice:

    Acciones en un hilo antes de enviar un objeto Ejecutable a un Ejecutor antes de que comience su ejecución, tal vez en otro hilo.

    Entonces, en su ejemplo, se garantiza que "foo" es parte de list1 en su lambda y que list2 es visible en etapas posteriores.

  2. Esto es básicamente cubierto por la documentación del Executor .