Les contrats à terme et promesses bloquent jusqu'à ce qu’ils ont calculé leurs valeurs, alors quelle est la différence entre eux ?
Réponses
Trop de publicités?Répondre en Clojure conditions, voici quelques exemples de Sean Devlin du screencast:
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
Notez que dans la promesse vous sont explicitement offrir une valeur que vous sélectionnez plus tard dans un calcul (:fred
dans ce cas). L'avenir, d'autre part, est consommée au même endroit qu'il a été créé. L' some-expr
est probablement lancé en coulisses et calculé en tandem (un jour), mais si elle reste non évaluée par le temps, il est accessible le thread se bloque jusqu'à ce qu'il est disponible.
edité pour ajouter
Pour aider à distinguer entre une promesse et d'avenir, notez les points suivants:
promesse
- Vous créez un
promise
. Cette promesse objet peut maintenant être transmis à n'importe quel thread. - Vous continuez avec les calculs. Ceux-ci peuvent être très compliqués calculs concernant les effets secondaires, le téléchargement de données, la saisie de l'utilisateur, l'accès à la base, d'autres promesses -- ce que vous voulez. Le code ressemblera beaucoup à celle de votre réseau principal au code dans n'importe quel programme.
- Lorsque vous aurez terminé, vous pourrez
deliver
les résultats de cette promesse de l'objet. - Tout article qui tente d'
deref
votre promesse avant que vous avez terminé avec votre calcul bloquera jusqu'à ce que vous avez terminé. Une fois que vous avez terminé et vous avezdeliver
ed la promesse, la promesse de ne pas bloquer plus longtemps.
l'avenir
- Vous créez votre avenir. Une partie de votre avenir, c'est une expression pour le calcul.
- L'avenir peut ou ne peut pas exécuter simultanément. Il pourrait être attribué à un fil, éventuellement à partir d'un pool. Il pourrait juste attendre et ne rien faire. De votre point de vue, on ne peut pas dire.
- À un certain point, vous (ou un autre thread)
deref
s l'avenir. Si le calcul a déjà terminé, vous obtenez les résultats. Si elle n'a pas déjà terminé, vous pouvez bloquer jusqu'à ce qu'il est. (On peut supposer que si il n'a pas encore commencé,deref
ing, cela signifie qu'il commence à s'exécuter, mais cela, aussi, n'est pas garantie.)
Alors que vous pourriez faire de l'expression dans l'avenir aussi compliqué que le code qui suit la création d'une promesse, il est douteux que c'est souhaitable. Cela signifie que les contrats à terme sont vraiment plus adapté à rapide, de fond en mesure de calculs tandis que les promesses sont vraiment plus adaptée à de grands complexes, de chemins d'exécution. Aussi, les promesses semblent, en termes de calculs disponibles, un peu plus flexible et orienté vers la promesse créateur de faire le travail, et un autre thread récolter la moisson. Les contrats à terme sont plus orientés vers automatiquement à partir d'un thread (sans le laid et le risque d'erreur de surcharge) et passe à d'autres choses jusqu'à ce que vous -- le thread d'origine, doivent avoir les résultats.
À la fois l'Avenir et la Promesse sont des mécanismes permettant de communiquer le résultat de l'asynchrone calcul du Producteur au Consommateur(s).
Dans le cas d' Avenir, le calcul est défini au moment de la création et de l'exécution asynchrone commence "dès que possible". Il a également "sait" comment frayer un calcul asynchrone.
Dans le cas de la Promesse, le calcul, son heure de début et [possible] invocation asynchrone sont découplées du mécanisme de livraison. Lorsque le calcul des résultats Producteur doit appeler deliver
explicitement, ce qui signifie également que les contrôles sur les Producteurs lorsque le résultat devient disponible.
Pour les Promesses Clojure fait une erreur de conception en utilisant le même objet (le résultat de l' promise
appel) à la fois de produire (deliver
) et de consommer (deref
) le résultat du calcul. Ce sont deux fonctions distinctes et doivent être traités comme tels.
Il existe déjà d'excellentes réponses de manière à ajouter seulement le "comment utiliser" résumé:
Les deux
La création de la promesse ou de l'avenir renvoie une référence immédiatement. Ce blocs de référence sur @/deref jusqu'au résultat du calcul est fourni par un autre thread.
L'avenir
Lors de la création de l'avenir de vous fournir un travail synchrone à faire. Il est exécuté dans un thread dédié à la surabondance de la piscine.
Promesse
Vous donnez aucun argument lors de la création de la promesse. La référence doit être transmis à une autre "utilisateur" ou " thread deliver
le résultat.
Tout d'abord, Promise
est Future
. Je pense que vous voulez savoir la différence entre un Promise
et FutureTask
.
Un Future
représente une valeur qui n'est actuellement pas connue, mais seront connus dans le futur.
Un FutureTask
représente le résultat d'un calcul qui va se passer dans l'avenir (peut-être dans certains pool de threads). Lorsque vous essayez d'accéder au résultat, si le calcul n'est pas encore arrivé, il bloque. Sinon, le résultat est immédiatement retourné. Il n'y a aucune autre partie impliquée dans le calcul du résultat que le calcul est spécifié par vous-même à l'avance.
Un Promise
représente un résultat qui sera livré par le promiser pour le stipulant dans l'avenir. Dans ce cas, vous êtes le stipulant et le promiser est que celui qui vous a donné l' Promise
objet. Semblable à l' FutureTask
, si vous essayez d'accéder au résultat avant de l' Promise
a été atteint, il reste bloqué jusqu'à la promiser remplit l' Promise
. Une fois l' Promise
est remplie, vous pouvez obtenir la même valeur de toujours et immédiatement. Contrairement à un FutureTask
, il y a une autre partie impliquée ici, celui qui a fait l' Promise
. Qu'une autre partie est responsable de faire le calcul et l'accomplissement de l' Promise
.
En ce sens, un FutureTask
est Promise
vous faites pour vous-même.