future と promise はどちらも値を計算するまでブロックしますが、両者の違いは何ですか?
6 に答える
Clojure 用語で答えると、 Sean Devlin のスクリーンキャストからの例がいくつかあります。
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
promise では、後の計算で選択した値を明示的に配信していることに注意してください (:fred
この場合)。一方、未来は、それが作られた場所で消費されています。はsome-expr
おそらく舞台裏で起動され、(最終的には) 並行して計算されますが、アクセスされるまでに未評価のままである場合、スレッドは使用可能になるまでブロックされます。
編集して追加
promise と future をさらに区別するために、次の点に注意してください。
約束
- を作成し
promise
ます。その promise オブジェクトを任意のスレッドに渡すことができるようになりました。 - 計算を続行します。これらは、副作用、データのダウンロード、ユーザー入力、データベースへのアクセス、その他の約束など、好きなものを含む非常に複雑な計算になる可能性があります。コードは、どのプログラムのメインライン コードにもよく似ています。
- 終了したら
deliver
、結果をその promise オブジェクトに渡すことができます。 - 計算が完了する前に約束を守ろうとする項目は
deref
、計算が完了するまでブロックされます。完了deliver
して promise を編集すると、promise はブロックされなくなります。
将来
- あなたの未来を作るのはあなたです。あなたの未来の一部は、計算式です。
- future は同時に実行される場合と実行されない場合があります。おそらくプールから、スレッドを割り当てることができます。ただ待つだけで、何もしない可能性があります。あなたの観点からは、あなたにはわかりません。
- ある時点で、あなた (または別のスレッド)
deref
が未来になります。計算がすでに完了している場合は、その結果が得られます。まだ完了していない場合は、完了するまでブロックします。(おそらく、まだ開始されていない場合はderef
、実行が開始されていることを意味しますが、これも保証されていません。)
プロミスの作成に続くコードと同じくらい複雑な式を将来作成することはできますが、それが望ましいかどうかは疑わしいです。これは、future が迅速でバックグラウンド可能な計算により適しているのに対し、promise は大規模で複雑な実行パスにより適していることを意味します。また、Promise は、利用可能な計算に関しては、もう少し柔軟で、Promise の作成者が作業を行い、別のスレッドが収穫を得る方向に向けられているように見えます。フューチャーは、自動的にスレッドを開始し (醜くてエラーが発生しやすいオーバーヘッドなしで)、元のスレッドが結果を必要とするまで他の処理を続行する方向に向いています。
Future と Promise はどちらも、プロデューサからコンシューマに非同期計算の結果を伝えるメカニズムです。Future
の
場合、計算は Future の作成時に定義され、非同期実行は "ASAP" で開始されます。また、非同期計算を生成する方法も「知っています」。Promise the computeの
場合、その開始時間と [可能な]非同期呼び出しは、配信メカニズムから切り離されます。計算結果が利用可能になると、Producer は明示的に呼び出す必要があります。これは、Producer がいつ結果が利用可能になるかを制御することも意味します。 deliver
Promisesの
場合、Clojure は計算結果の生成 ( ) と消費 ( ) のpromise
両方に同じオブジェクト (呼び出しの結果) を使用するという設計ミスを犯します。これらは 2 つの非常に異なる機能であり、そのように扱う必要があります。deliver
deref
まず、 aPromise
は aFuture
です。Promise
aと aの違いを知りたいと思いますFutureTask
。
AFuture
は、現時点では不明であるが、将来判明するであろう値を表します。
AFutureTask
は、将来 (おそらくスレッド プールで) 発生する計算の結果を表します。結果にアクセスしようとすると、計算がまだ行われていない場合はブロックされます。それ以外の場合、結果はすぐに返されます。計算は事前に指定されているため、結果の計算に第三者が関与することはありません。
APromise
は、将来、プロミスによってプロミスに届けられる結果を表す。この場合、あなたは約束者であり、約束者はあなたにPromise
物を与えた人です。と同様に、が満たさFutureTask
れる前に結果にアクセスしようとするとPromise
、プロミスが を満たすまでブロックされPromise
ます。が満たされるPromise
と、常に同じ値がすぐに得られます。とは異なり、FutureTask
ここには を作成した別の当事者が関与していますPromise
。別の当事者が計算を行い、Promise
.
その意味で、aFutureTask
はPromise
あなたが自分自身に作ったものです。