Я пытаюсь понять, есть ли какие-либо гарантии видимости, предоставляемые CompletableFuture
.
Предположим, у меня есть класс с именем SampleClass
, который выглядит примерно так:
public class SampleClass {
private String member1;
private String member2;
// getters, setters and constructor;
}
И я делаю что-то вроде этого:
SampleClass sampleClass = new SampleClass();
CompletableFuture<Void> cf1 = CompletableFuture.supplyAsync(() -> "Hello")
.thenAccept(sampleClass::setMember1);
CompletableFuture<Void> cf2 = CompletableFuture.supplyAsync(() -> " World")
.thenAccept(sampleClass::setMember2);
cf1.join();
cf2.join();
// sout(sampleClass);
Теперь я хочу понять, что в операторе sout
может ли быть случай, когда один или оба члена не инициализированы?
В принципе, есть ли здесь какие-либо гарантии видимости, предоставляемые CompletableFuture
? (У меня сложилось впечатление, что CompletableFuture
не дает такой гарантии, а приведенный выше код не работает.)
Я уже рассмотрел этот вопрос, но думаю, что это не то, что мне нужно .
join()
— это удобная альтернативаget()
. ИFuture.get()
было рассмотрено в документация по пакету. Конечно, было бы неплохо, если бы они расширили эту часть для функций Java 8. Но я по-прежнему считаю его нынешнюю форму достаточной для обеспечения правильной видимости памяти. С одной оговоркой, другого завершения быть не должно. Поскольку любой может вызватьcomplete
наCompletableFuture
, такой вызов аннулирует любые гарантии любого завершения, поскольку вы не знаете, что выиграет. - person Holger   schedule 04.05.2020Future.get()
гарантирует, что произойдет до любого действия, следующего заFuture.get()
, поэтому вызовcf2.join()
должен видеть обновленное значениеsampleClass
. Правильно ли я понимаю? И этой гарантии видимости не будет, если откуда-то мы позвонимCompletableFuture.complete()
, верно? - person Lavish Kothari   schedule 04.05.2020join()
, однако вам потребуется безопасный способ определить, какое завершение было выполнено. был. Для типичного случая вычисления функций, которые выдают результат, безопасно использовать значение, возвращаемоеjoin()
, так как оно является результатом успешного завершения. Но это не работает для побочного эффекта, такого какsetMember2
. То же самое относится кCompletableFuture.anyOf(c1, c2).join()
; это не даст вам никаких гарантий. - person Holger   schedule 05.05.2020