フューチャーとプロミスはどちらも、値を計算するまでブロックされます。では、両者の違いは何ですか?
フューチャーとプロミスはどちらも、値を計算するまでブロックされます。では、両者の違いは何ですか?
回答:
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
あなたが自分で作ったものです。