フューチャーとプロミスはどちらも、値を計算するまでブロックされます。では、両者の違いは何ですか?
フューチャーとプロミスはどちらも、値を計算するまでブロックされます。では、両者の違いは何ですか?
回答:
Clojureの用語で答えると、SeanDevlinのスクリーンキャストからのいくつかの例があります。
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
promiseでは、後の計算(:fredこの場合)で選択した値を明示的に提供していることに注意してください。一方、未来はそれが作成されたのと同じ場所で消費されています。some-exprおそらく舞台裏立ち上げ、タンデム(最終的に)で計算され、それは、時間によって評価されないままであれば、それが利用可能になるまでには、スレッドブロックをアクセスされています。
追加するために編集
約束と未来をさらに区別するために、次の点に注意してください。
promiseます。そのpromiseオブジェクトを任意のスレッドに渡すことができるようになりました。deliverそのpromiseオブジェクトに結果を表示できます。deref計算が完了する前に約束をしようとするアイテムは、完了するまでブロックされます。完了しdeliverてプロミスを実行すると、プロミスはブロックされなくなります。derefは未来です。計算がすでに完了している場合は、その結果を取得します。まだ完了していない場合は、完了するまでブロックします。(おそらく、まだ開始されていない場合derefは、実行を開始することを意味しますが、これも保証されません。)将来、promiseの作成に続くコードと同じくらい複雑な式を作成することはできますが、それが望ましいかどうかは疑わしいです。つまり、先物は迅速でバックグラウンド可能な計算に非常に適していますが、promiseは大規模で複雑な実行パスに非常に適しています。あまりにも、利用可能な計算の観点から、約束はもう少し柔軟で、仕事をしている約束の作成者と収穫を刈り取る別のスレッドに向けられているようです。先物は、スレッドを自動的に開始し(醜くエラーが発生しやすいオーバーヘッドなしで)、元のスレッドが結果を必要とするまで他のことを続けることをより重視しています。
future通話の本文にはN個のsexprを含めることができます。
FutureとPromiseはどちらも、非同期計算の結果をプロデューサーからコンシューマーに伝達するメカニズムです。Futureの
場合、計算はFutureの作成時に定義され、非同期実行は「ASAP」で開始されます。また、非同期計算を生成する方法も「知っています」。
以下の場合にはプロミス演算、その開始時間と【可能】非同期呼び出しは、送達機構から分離されています。ときの計算結果が利用可能であるプロデューサーは、呼び出す必要があります。また、そのプロデューサーコントロールを意味し、明示する場合、結果が利用可能になります。 deliver
以下のために約束のClojureは同じオブジェクト(の結果使用して、設計ミスをするpromise(両方生成するコール)deliver)及び(消費deref)の結果を計算。これらは2つの非常に異なる機能であり、そのように扱う必要があります。
promiseするのが便利かどうかはわかりません。「邪悪な」消費者はまれです。約束の上に独自の抽象化を構築することを妨げるものは何もありません。
(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))))
すでに優れた答えがあるので、「使い方」の要約を追加するだけです。
両方とも
promiseまたはfutureを作成すると、参照がすぐに返されます。この参照は、計算結果が他のスレッドによって提供されるまで、@ / derefでブロックされます。
未来
フューチャーを作成するときは、実行する同期ジョブを提供します。専用の無制限プールからのスレッドで実行されます。
約束する
promiseを作成するときは、引数を指定しません。参照はdeliver、結果になる他の「ユーザー」スレッドに渡される必要があります。
Clojureのでは、promise、future、とdelay約束のようなオブジェクトです。これらはすべて、クライアントがderef(または@)を使用して待機できる計算を表します。クライアントは結果を再利用するため、計算が数回実行されることはありません。
これらは、計算の実行方法が異なります。
future別のワーカースレッドで計算を開始します。deref結果の準備ができるまでブロックします。
delay最初のクライアントが、、derefまたはを使用すると、計算が遅延して実行されますforce。
promise結果はを使用してカスタムの方法で配信されるため、最も柔軟性がありますdeliver。どちらfutureでもない場合、またはdelayユースケースと一致しない場合に使用します。
まず、aPromiseはFutureです。aPromiseとaの違いを知りたいと思いますFutureTask。
AFutureは、現在は不明ですが、将来は既知になる値を表します。
AFutureTaskは、将来(おそらくいくつかのスレッドプールで)発生する計算の結果を表します。結果にアクセスしようとすると、計算がまだ行われていない場合はブロックされます。それ以外の場合、結果はすぐに返されます。計算は事前に指定されているため、結果の計算に関与する他の当事者は存在しません。
APromiseは、将来、約束者から約束者に配信される結果を表します。この場合、あなたは約束者であり、約束者はあなたにPromiseオブジェクトを与えた人です。と同様に、FutureTaskが実行される前に結果にアクセスしようとするとPromise、約束者がが実行されるまで結果はブロックされPromiseます。いったんPromise満たされ、いつでも、すぐに同じ値を取得します。とは異なり、FutureTaskここには別のパーティが含まれていPromiseます。その別の当事者は、計算を実行し、を実行する責任がありPromiseます。
その意味で、aFutureTaskはPromiseあなたが自分で作ったものです。