Какая разница между Future
а Promise
?
Они оба действуют как заполнитель для будущих результатов, но где главное отличие?
java
concurrency
future
promise
user1170330
источник
источник
Promise
и это зависит от вас, чтобы сохранить его. Когда кто-то еще дает вам обещание, вы должны подождать, чтобы увидеть, соблюдают ли они его вFuture
Ответы:
Согласно этому обсуждению ,
Promise
наконец-то был вызванCompletableFuture
для включения в Java 8, и его Javadoc объясняет:Пример также приведен в списке:
Обратите внимание, что финальный API немного отличается, но допускает аналогичное асинхронное выполнение:
источник
(Пока я не совсем доволен ответами, так что моя попытка ...)
Я думаю, что комментарий Кевина Райта ( «Вы можете сделать Обещание, и вы должны его выполнить. Когда кто-то еще дает вам обещание, вы должны подождать, чтобы увидеть, выполнят ли они его в будущем» ), суммирует его довольно хорошо, но некоторые объяснение может быть полезным.
Фьючерсы и обещания - это довольно похожие понятия, разница в том, что будущее - это контейнер только для чтения для результата, которого еще нет, а обещание можно написать (обычно только один раз). Java 8 CompletableFuture и Guava SettableFuture можно рассматривать как обещания, поскольку их значение может быть установлено («завершено»), но они также реализуют интерфейс Future, поэтому для клиента нет никакой разницы.
Результат будущего будет установлен «кем-то другим» - результатом асинхронного вычисления. Обратите внимание, что FutureTask - классическое будущее - нужно инициализировать с помощью Callable или Runnable, конструктор без аргументов отсутствует, а FutureTask и FutureTask доступны только для чтения извне (методы набора FutureTask защищены). Значение будет установлено на результат вычисления изнутри.
С другой стороны, результат обещания может быть установлен «вами» (или фактически кем угодно) в любое время, потому что у него есть метод открытого сеттера. И CompletableFuture, и SettableFuture могут быть созданы без каких-либо задач, и их значение может быть установлено в любое время. Вы отправляете обещание клиентскому коду и выполняете его позже, как пожелаете.
Обратите внимание, что CompletableFuture не является «чистым» обещанием, его можно инициализировать с помощью задачи, аналогичной FutureTask, и его наиболее полезная функция - это не связанная цепочка этапов обработки.
Также обратите внимание, что обещание не обязательно должно быть подтипом будущего и не обязательно должно быть одним и тем же объектом. В Scala объект Future создается асинхронным вычислением или другим объектом Promise. В C ++ ситуация аналогична: объект обещания используется производителем, а объект будущего - потребителем. Преимущество такого разделения заключается в том, что клиент не может установить ценность будущего.
И Spring, и EJB 3.1 имеют класс AsyncResult, который похож на обещания Scala / C ++. AsyncResult реализует Future, но это не настоящее будущее: асинхронные методы в Spring / EJB возвращают другой объект Future, доступный только для чтения, посредством некоторой фоновой магии, и это второе «реальное» будущее может использоваться клиентом для доступа к результату.
источник
Я знаю, что уже есть принятый ответ, но все же хотел бы добавить свои два цента:
TLDR: будущее и обещание - это две стороны асинхронной операции: потребитель / вызывающий абонент против производителя / разработчика .
Как вызывающий асинхронного метод API, вы получите в
Future
качестве ручки для результата вычислению в. Например, вы можете вызватьget()
его, чтобы дождаться завершения вычислений и получить результат.Теперь подумайте, как на самом деле реализован этот метод API: разработчик должен
Future
немедленно вернуть a . Они несут ответственность за завершение этого будущего, как только вычисление будет выполнено (что они узнают, поскольку оно реализует логику диспетчеризации ;-)). Они будут использоватьPromise
/,CompletableFuture
чтобы сделать именно это: сконструировать и вернутьCompletableFuture
сразу, и вызвать, какcomplete(T result)
только вычисление будет сделано.источник
Я приведу пример того, что такое Promise и как его значение может быть установлено в любое время, в отличие от Future, значение которого доступно только для чтения.
Предположим, у вас есть мама, и вы просите у нее денег.
Выход этого:
Мамины обещания были созданы, но ждали какого-то «завершения» мероприятия.
Вы создали такое событие, принимая ее обещание и объявляя о своих планах поблагодарить маму:
В этот момент мама начала открывать сумочку ... но очень медленно ...
и отец вмешался намного быстрее и выполнил обещание вместо твоей мамы
Вы заметили исполнителя, который я написал явно?
Интересно, что если вместо этого вы используете неявного исполнителя по умолчанию (commonPool), а папа не дома, а только мама с ее «медленным кошельком», то ее обещание будет выполнено только в том случае, если программа живет дольше, чем мама должна получить деньги от кошелек.
Исполнитель по умолчанию действует как «демон» и не ожидает выполнения всех обещаний. Я не нашел хорошего описания этого факта ...
источник
Не уверен, что это может быть ответом, но, как я вижу, что другие говорили о ком-то, может показаться, что вам нужны две отдельные абстракции для обеих этих концепций, так что одна из них (
Future
) является представлением только для чтения (Promise
) ... но на самом деле это не нужно.Например, посмотрите, как определяются обещания в javascript:
https://promisesaplus.com/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
Основное внимание уделяется компоновке с использованием такого
then
метода, как:что делает асинхронные вычисления похожими на синхронные:
что довольно круто (Не так круто, как async-await, но async-await просто удаляет шаблон .... затем (function (result) {.... from it).
И на самом деле их абстракция довольно хороша как конструктор обещаний
позволяет вам предоставить два обратных вызова, которые можно использовать для
Promise
успешного завершения или с ошибкой. Таким образом, только код,Promise
который создаетPromise
объект, может завершить его, а код, который получает уже созданный объект, имеет представление только для чтения.С наследованием вышеупомянутое может быть достигнуто, если решить и отклонить являются защищенными методами.
источник
CompletableFuture
может иметь некоторое сходство с a,Promise
но это все же не такPromise
, потому что способ, которым он предназначен для использования, отличается: результат aPromise
потребляется при вызовеthen(function)
, а функция выполняется в контексте производителя сразу после вызова производителяresolve
,Future
Результат A потребляется вызовом,get
который заставляет поток потребителя ждать, пока поток производителя не сгенерирует значение, а затем обрабатывает его в потребителе.Future
по своей сути многопоточный, но ...Promise
только с одним потоком (и фактически это именно та среда, для которой они были изначально разработаны: приложения javascript обычно имеют только один поток, поэтому вы не можете реализовать ихFuture
там).Promise
поэтому он намного легче и эффективнееFuture
, ноFuture
может быть полезен в ситуациях, которые являются более сложными и требуют взаимодействия между потоками, которые не могут быть легко организованы с помощьюPromise
s. Подводя итог:Promise
это модель push, в то времяFuture
как модель pull (ср. Iterable против Observable)XMLHttpRequest
). Я не верю утверждению эффективности, у вас есть какие-то цифры? +++ При этом очень хорошее объяснение.get
неразрешенного решенияFuture
обязательно потребует двухпоточных переключений контекста, что, по крайней мере, несколько лет назад могло потребовать около 50 человек .Для клиентского кода Promise предназначен для наблюдения или присоединения обратного вызова, когда результат доступен, тогда как Future должен ждать результата и затем продолжать. Теоретически все, что можно сделать с фьючерсами, что можно сделать с обещаниями, но из-за разницы в стиле, результирующий API для обещаний на разных языках облегчает цепочку.
источник
Не задан метод в интерфейсе Future, только метод get, поэтому он доступен только для чтения. О CompletableFuture эта статья может быть полезной. completablefuture
источник