Как фьючерсы Clojure и promises отличаются?

Оба фьючерса и promises блокируются до тех пор, пока они не рассчитают свои значения, поэтому в чем разница между ними?

Ответ 1

Отвечая на термины Clojure, вот несколько примеров из Sean Devlin screencast:

(def a-promise (promise))
(deliver a-promise :fred)

(def f (future (some-sexp)))
(deref f)

Обратите внимание, что в обещании вы явно предоставляете значение, которое вы выбираете при более позднем вычислении (:fred в этом случае). С другой стороны, будущее потребляется в том же месте, в котором оно было создано. some-expr предположительно запускается за кулисами и вычисляется в тандеме (в конечном счете), но если он остается неудовлетворенным к тому времени, когда к нему обращаются, поток блокируется до тех пор, пока он не будет доступен.


отредактировано для добавления

Чтобы лучше провести различие между обещанием и будущим, обратите внимание на следующее:

обещание

  • Вы создаете promise. Этот объект обещания теперь можно передать любому потоку.
  • Вы продолжаете вычисления. Это могут быть очень сложные вычисления, связанные с побочными эффектами, загрузка данных, вход пользователя, доступ к базе данных, другие promises - все, что вам нравится. Код будет очень похож на ваш код основной линии в любой программе.
  • Когда вы закончите, вы можете deliver получить результаты этого объекта обещания.
  • Любой элемент, который пытается выполнить deref ваше обещание до того, как вы закончите с вашими расчетами, будет заблокирован, пока вы не закончите. Как только вы закончите, и вы deliver изложите обещание, обещание больше не будет блокировать.

будущее

  • Вы создаете свое будущее. Часть вашего будущего является выражением для расчета.
  • Будущее может или не может выполняться одновременно. Ему может быть назначен поток, возможно, из пула. Он мог просто ждать и ничего не делать. С вашей точки зрения вы не можете сказать.
  • В какой-то момент вы (или другой поток) deref будущее. Если расчет уже завершен, вы получите его результаты. Если он еще не завершен, вы блокируете его. (Предположительно, если он еще не начался, deref ing означает, что он начинает выполняться, но это тоже не гарантируется.)

В то время как может сделать выражение в будущем столь же сложным, как и код, который следует за созданием обещания, сомнительно, что это желательно. Это означает, что фьючерсы действительно больше подходят для быстрых вычислений с учетом возможностей, в то время как promises действительно больше подходят для больших и сложных путей выполнения. Тоже, promises кажется, с точки зрения доступных вычислений, немного более гибким и ориентированным на создателя обещаний, выполняющего работу, и другой поток, пожинающий урожай. Фьючерсы более ориентированы на автоматическое начало потока (без уродливых и подверженных ошибкам накладных расходов) и продолжаются с другими вещами, пока вы - исходный поток - не нуждаетесь в результатах.

Ответ 2

И будущее, и обещание - это механизмы для передачи результата асинхронного вычисления от Продюсера к Потребителю (-ам). В случае Будущее вычисление определяется во время создания Будущего, а асинхронное выполнение начинается "КАК МОЖНО СКОРЕЕ". Он также "знает", как порождать асинхронное вычисление.

В случае Promise вычисление, его время начала и [возможный] асинхронный вызов отключаются от механизма доставки. Когда результат вычисления доступен Продюсер должен явно вызывать deliver, что также означает, что Producer управляет, когда результат становится доступным.

Для Promises Clojure возникает ошибка проектирования, используя тот же объект (результат вызова promise), чтобы произвести (deliver) и потреблять (deref) результат вычисления, Это две очень разные возможности и должны рассматриваться как таковые.

Ответ 3

Есть уже отличные ответы, поэтому добавьте только "как использовать":

И

Создание обещания или будущего немедленно возвращает ссылку. Эта ссылка блокируется на @/deref до тех пор, пока результат вычисления не будет предоставлен другим потоком.

Future

При создании будущего вы предоставляете синхронное задание. Он выполнен в потоке из выделенного неограниченного пула.

Promise

Вы не даете аргументов при создании обещания. Ссылка должна быть передана в другой поток пользователя, который будет deliver результатом.

Ответ 4

Во-первых, a Promise является Future. Я думаю, вы хотите узнать разницу между Promise и a FutureTask.

A Future представляет значение, которое в настоящее время не известно, но будет известно в будущем.

A FutureTask представляет результат вычисления, которое произойдет в будущем (возможно, в некотором пуле потоков). Когда вы пытаетесь получить доступ к результату, если вычисление еще не произошло, оно блокируется. В противном случае результат немедленно возвращается. Нет другой стороны, участвующей в вычислении результата, поскольку вычисление заранее указано вами.

A Promise представляет собой результат, который в будущем будет предоставлен обезврежителем к обещанию. В этом случае вы являетесь обещанием, а обещатель - тем, кто дал вам объект Promise. Подобно FutureTask, если вы пытаетесь получить доступ к результату до выполнения Promise, он блокируется до тех пор, пока promiser не выполнит Promise. После выполнения Promise вы получаете одно и то же значение всегда и сразу. В отличие от FutureTask, здесь участвует другая сторона, которая сделала Promise. Эта другая сторона несет ответственность за выполнение вычислений и выполнение Promise.

В этом смысле a FutureTask является Promise, который вы сделали для себя.