Sia i futures che le promesse si bloccano fino a quando non hanno calcolato i loro valori, quindi qual è la differenza tra loro?
Sia i futures che le promesse si bloccano fino a quando non hanno calcolato i loro valori, quindi qual è la differenza tra loro?
Risposte:
Rispondendo in termini di Clojure, ecco alcuni esempi dallo screencast di Sean Devlin :
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
Si noti che nella promessa si fornisce esplicitamente un valore selezionato in un calcolo successivo ( :fredin questo caso). Il futuro, invece, si consuma nello stesso luogo in cui è stato creato. Il some-exprè presumibilmente lanciato dietro le quinte e calcolato in tandem (eventualmente), ma se rimane non valutata dal tempo si accede al blocchi di filettatura finché non è disponibile.
modificato per aggiungere
Per aiutare a distinguere ulteriormente tra una promessa e un futuro, nota quanto segue:
promise. Quell'oggetto promessa può ora essere passato a qualsiasi thread.deliver i risultati di quell'oggetto promesso.derefmantenere la tua promessa prima che tu abbia finito con il tuo calcolo si bloccherà finché non avrai finito. Una volta che hai finito e hai modificato deliverla promessa, la promessa non si bloccherà più.derefil futuro. Se il calcolo è già stato completato, ne ottieni i risultati. Se non è già stato completato, blocchi finché non lo ha fatto. (Presumibilmente, se non è ancora iniziato, derefsignifica che inizia l'esecuzione, ma anche questo non è garantito.)Anche se in futuro potresti rendere l'espressione complicata come il codice che segue la creazione di una promessa, è dubbio che sia desiderabile. Ciò significa che i futures sono davvero più adatti a calcoli rapidi e in background, mentre le promesse sono davvero più adatte a percorsi di esecuzione ampi e complicati. Inoltre, le promesse sembrano, in termini di calcoli disponibili, un po 'più flessibili e orientate verso il creatore della promessa che fa il lavoro e un altro filo che raccoglie il raccolto. I futuri sono più orientati verso l'avvio automatico di un thread (senza il sovraccarico brutto e soggetto a errori) e andare avanti con altre cose fino a quando tu - il thread di origine - hai bisogno dei risultati.
futurechiamata può includere N sexprs.
Sia Future che Promise sono meccanismi per comunicare il risultato del calcolo asincrono dal produttore al consumatore (i).
In caso di Future, il calcolo è definito al momento della creazione di Future e l'esecuzione asincrona inizia "ASAP". Inoltre "sa" come generare un calcolo asincrono.
In caso di Promise, il calcolo , la sua ora di inizio e [possibile] invocazione asincrona sono disaccoppiati dal meccanismo di consegna. Quando il risultato del calcolo è disponibile, Producer deve chiamare deliveresplicitamente, il che significa anche che Producer controlla quando risultato diventa disponibile.
For PromisesClojure commette un errore di progettazione utilizzando lo stesso oggetto (risultato della promisechiamata) sia per produrre ( deliver) che per consumare ( deref) il risultato del calcolo . Queste sono due capacità molto distinte e dovrebbero essere trattate come tali.
promisesarebbe conveniente. I consumatori "cattivi" sono rari; niente ti impedisce di costruire la tua astrazione in cima alle promesse.
(defn undeliverable-promise [] (let [p (promise)] (reify clojure.lang.IDeref (deref [_] (deref p)) clojure.lang.IBlockingDeref (deref [_ ms val] (deref p ms val)) clojure.lang.IPending (isRealized [_] (.isRealized p)) clojure.lang.IFn (invoke [_ _] nil))))
Ci sono già ottime risposte quindi aggiungendo solo il riepilogo "come usare":
Tutti e due
La creazione di promesse o future restituisce immediatamente un riferimento. Questo riferimento si blocca su @ / deref finché il risultato del calcolo non viene fornito da un altro thread.
Futuro
Quando crei il futuro, fornisci un lavoro sincrono da fare. Viene eseguito in un thread dal pool illimitato dedicato.
Promettere
Non dai argomenti quando crei una promessa. Il riferimento dovrebbe essere passato ad un altro thread "utente" che ne darà deliveril risultato.
In Clojure, promise, future, e delaysono promessa come oggetti. Rappresentano tutti un calcolo che i client possono attendere utilizzando deref(o @). I client riutilizzano il risultato, in modo che il calcolo non venga eseguito più volte.
Differiscono nel modo in cui viene eseguito il calcolo:
futureinizierà il calcolo in un diverso thread di lavoro. derefsi bloccherà fino a quando il risultato non sarà pronto.
delayeseguirà il calcolo pigramente, quando il primo client usa deref, o force.
promiseoffre la massima flessibilità, poiché il risultato viene fornito in qualsiasi modo personalizzato utilizzando deliver. Lo usi quando nessuno dei due futureo delaycorrisponde al tuo caso d'uso.
In primo luogo, a Promiseè a Future. Penso che tu voglia conoscere la differenza tra a Promisee a FutureTask.
A Futurerappresenta un valore che non è attualmente noto ma lo sarà in futuro.
A FutureTaskrappresenta il risultato di un calcolo che avverrà in futuro (forse in qualche pool di thread). Quando si tenta di accedere al risultato, se il calcolo non è ancora avvenuto, si blocca. In caso contrario, il risultato viene restituito immediatamente. Non ci sono altre parti coinvolte nel calcolo del risultato poiché il calcolo è stato specificato in anticipo.
A Promiserappresenta un risultato che verrà consegnato dal promettente al promesso in futuro. In questo caso tu sei il promesso e il promettente è colui che ti ha dato l' Promiseoggetto. Simile a FutureTask, se si tenta di accedere al risultato prima che Promisesia stato soddisfatto, viene bloccato fino a quando il promettente non soddisfa il Promise. Una volta Promisesoddisfatto, ottieni sempre e immediatamente lo stesso valore. A differenza di a FutureTask, qui è coinvolta un'altra parte, che ha creato il file Promise. Che un'altra parte sia responsabile per il calcolo e l'adempimento del Promise.
In questo senso, a FutureTaskè un Promisefatto a te stesso.