Comment les futures Clojure et promesses diffèrent?
-
30-09-2019 - |
Question
Les deux contrats à terme et des promesses de bloquer jusqu'à ce qu'ils ont calculé leurs valeurs, alors quelle est la différence entre eux?
La solution
Répondre en termes Clojure, voici quelques exemples de screencast de Sean Devlin :
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
Notez que dans la promesse que vous livrez explicitement une valeur que vous sélectionnez dans un calcul plus tard (:fred
dans ce cas). L'avenir, d'autre part, est consommée au même endroit qu'il a été créé. Le some-expr
est probablement lancé dans les coulisses et calculées en tandem (éventuellement), mais si elle reste non évaluée au moment où il est accessible aux blocs de fil jusqu'à ce qu'il soit disponible.
sous la direction d'ajouter
De manière à distinguer entre une promesse et un avenir, noter ce qui suit:
promesse
- Vous créez un
promise
. Cet objet promesse peut maintenant être transmis à un fil. - Vous continuez avec les calculs. Ceux-ci peuvent être des calculs très complexes impliquant des effets secondaires, le téléchargement de données, l'entrée d'utilisateur, l'accès base de données, d'autres promesses - tout ce que vous aimez. Le code ressemblera beaucoup à votre code de ligne principale dans tout programme.
- Lorsque vous avez terminé, vous pouvez
deliver
les résultats à cet objet de promesse. - Tout élément qui tente de
deref
votre promesse avant que vous avez terminé votre calcul bloquera jusqu'à ce que vous avez terminé. Une fois que vous avez terminé et vous avezdeliver
ed la promesse, la promesse ne sera pas bloquer plus longtemps.
futur
- Vous créez votre avenir. Une partie de votre avenir est une expression pour le calcul.
- L'avenir peut ou ne peut pas exécuter en même temps. Il pourrait se voir attribuer un fil, peut-être d'une piscine. Il pourrait tout simplement attendre et ne rien faire. De votre point de vue vous ne pouvez pas dire .
- À un certain moment vous (ou un autre thread)
deref
s l'avenir. Si le calcul est déjà terminé, vous obtenez les résultats de celui-ci. Si elle n'a pas déjà terminé, vous bloquer jusqu'à ce qu'il ait. (On peut supposer que si elle n'a pas encore commencé,deref
ing cela signifie qu'il commence à exécuter, mais cela aussi est pas garantie.)
Alors que vous pourrait faire l'expression à l'avenir aussi compliqué que le code qui suit la création d'une promesse, il est douteux que est souhaitable. Cela signifie que des contrats à terme sont vraiment plus adaptés à des calculs rapides, tout en arrière-plan-mesure promesses sont vraiment plus adaptés aux grands chemins d'exécution complexes. Trop, promesses semblent, en termes de calculs disponibles, un peu plus flexible et orientée vers le créateur de la promesse de faire le travail et un autre fil la moisson. À terme sont plus orientés vers le démarrage automatique d'un fil (sans les frais généraux laid et sujettes à erreur) et en cours avec d'autres choses jusqu'à ce que vous - le fil d'origine -. Besoin des résultats
Autres conseils
Les deux futurs et la promesse sont des mécanismes de communication des résultats asynchrones calcul du producteur au consommateur (s).
En cas de Future calcul est défini au moment de la création et de l'exécution future async commence "dès que possible". Il a également « sait » comment frayer un calcul asynchrone.
En cas de Promesse calcul , son heure de début et [possible] appel asynchrone sont découplés du mécanisme de livraison . Lorsque calcul résultat est disponible Le producteur doit appeler explicitement deliver
, ce qui signifie également que le contrôle des producteurs lorsque résultat devient disponible.
Promesses Clojure fait une erreur de conception en utilisant le même objet (résultat d'appel promise
) à la fois des produits (deliver
) et de consommer (deref
) le résultat de calcul . Ce sont deux capacités très distinctes et doivent être traités comme tels.
Il y a déjà d'excellentes réponses afin d'ajouter que le résumé « comment utiliser »:
deux
Créer des rendements de promesse ou à venir immédiatement une référence. Ce blocs de référence sur @ / deref jusqu'à ce que résultat du calcul est fourni par un autre fil.
Future
Lors de la création future de vous fournir un travail synchrone à faire. Il est exécuté dans un thread du pool dédié sans bornes.
Promise
Vous donnez aucun argument lors de la création promesse. La référence fil doit être transmis à d'autres « utilisateur » qui deliver
le résultat.
Tout d'abord, un Promise
est un Future
. Je pense que vous voulez savoir la différence entre un Promise
et un FutureTask
.
A Future
représente une valeur qui est pas connue, mais sera connu dans l'avenir.
A FutureTask
représente le résultat d'un calcul qui va se passer à l'avenir (peut-être dans une piscine de fil). Lorsque vous essayez d'accéder au résultat, si le calcul n'a pas encore eu lieu, il bloque. Sinon, le résultat est retourné immédiatement. Il n'y a pas d'autre partie impliquée dans le calcul du résultat que le calcul est spécifié par vous à l'avance.
A Promise
représente un résultat qui sera délivré par le Promiser au promisee à l'avenir. Dans ce cas, vous êtes le promisee et le Promiser est que celui qui vous a donné l'objet Promise
. Semblable à la FutureTask
, si vous essayez d'accéder au résultat avant la Promise
a été remplie, il est bloqué jusqu'à ce que le Promiser remplit la Promise
. Une fois que la Promise
est remplie, vous obtenez la même valeur toujours et immédiatement. Contrairement à un FutureTask
, il y a une autre partie impliquée ici, celui qui a fait le Promise
. Qu'une autre partie est responsable de faire le calcul et la réalisation du Promise
.
En ce sens, un FutureTask
est un Promise
que vous avez fait pour vous.