선물과 약속은 모두 가치를 계산할 때까지 차단됩니다. 그렇다면 이들의 차이점은 무엇입니까?
선물과 약속은 모두 가치를 계산할 때까지 차단됩니다. 그렇다면 이들의 차이점은 무엇입니까?
답변:
Clojure 용어로 대답하면 다음은 Sean Devlin의 스크린 캐스트의 몇 가지 예입니다 .
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
promise에서는 나중에 계산 ( :fred
이 경우)에서 선택한 값을 명시 적으로 제공합니다 . 반면에 미래는 창조되었던 곳에서 소비되고 있습니다. 은 some-expr
아마도 뒤에서 출시 탠덤 (결국)에서 계산하지만 시간에 의해 평가되지 않은 남아있는 경우 사용할 수있을 때까지이 스레드 블록을 액세스 할 수있다.
추가하기 위해 편집 됨
약속과 미래를 더 잘 구별하려면 다음 사항에 유의하십시오.
promise
. 이제 약속 객체를 모든 스레드에 전달할 수 있습니다.deliver
약속 객체에 대한 결과를 얻을 수 있습니다 .deref
계산이 끝나기 전에 약속 을 시도하는 모든 항목 은 완료 될 때까지 차단됩니다. 완료 deliver
하고 약속을 준수하면 약속이 더 이상 차단되지 않습니다.deref
은 미래입니다. 계산이 이미 완료된 경우 결과를 얻을 수 있습니다. 아직 완료되지 않은 경우 완료 될 때까지 차단합니다. (아마도 아직 시작되지 않았다면 deref
실행이 시작되었음을 의미하지만 이것도 보장되지는 않습니다.)Promise 생성 이후의 코드만큼 복잡하게 표현할 수 있지만 , 그것이 바람직한지는 의심 스럽습니다. 즉, 미래는 빠르고 배경이 가능한 계산에 더 적합하고 약속은 크고 복잡한 실행 경로에 더 적합합니다. 또한 사용 가능한 계산 측면에서 약속은 작업을 수행하는 약속 생성자와 수확을 거두는 또 다른 스레드에 대해 조금 더 유연하고 지향적 인 것처럼 보입니다. 퓨처는 스레드를 자동으로 시작하고 (추악하고 오류가 발생하기 쉬운 오버 헤드없이) 원래 스레드가 결과를 필요로 할 때까지 다른 작업을 계속하는 방향으로 향합니다.
future
통화 본문 에는 N 개의 sexpr이 포함될 수 있습니다.
Future와 Promise는 모두 생산자에서 소비자에게 비동기 계산의 결과를 전달하는 메커니즘 입니다. Future 의
경우 계산 은 Future 생성시 정의되고 비동기 실행은 "ASAP"시작됩니다. 또한 비동기 계산을 생성하는 방법을 "알고"있습니다.
경우 약속 계산 , 그 개시 시간 및 [수] 비동기 호출이 전달기구로부터 분리된다. 경우 연산 결과 가능 프로듀서 호출해야 또한 생산자 제어 의미 명시 때 결과가 가능해진다. deliver
들어 약속 Clojure의 동일한 오브젝트 (의 결과를 사용하여 설계 실수를 promise
모두 생산 (에 호출) deliver
) 및 소비 ( deref
)의 결과를 계산 . 이는 매우 뚜렷한 두 가지 기능이므로 그렇게 취급해야합니다.
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에서 차단됩니다.
미래
미래를 만들 때 수행 할 동기 작업을 제공합니다. 제한되지 않은 전용 풀의 스레드에서 실행됩니다.
약속
약속을 만들 때 아무런 주장도하지 않습니다. 참조는 deliver
결과 가 될 다른 '사용자'스레드로 전달되어야합니다 .
Clojure의에서 promise
, future
그리고 delay
약속과 같은 개체입니다. 이들은 모두 클라이언트가 deref
(또는 @
) 을 사용하여 기다릴 수있는 계산을 나타냅니다 . 클라이언트는 결과를 재사용하므로 계산이 여러 번 실행되지 않습니다.
계산이 수행되는 방식이 다릅니다.
future
다른 작업자 스레드에서 계산을 시작합니다. deref
결과가 준비 될 때까지 차단됩니다.
delay
첫 번째 클라이언트가 deref
, 또는을 사용할 때 계산을 느리게 수행합니다 force
.
promise
를 사용하여 사용자 지정 방식으로 결과를 제공하므로 가장 큰 유연성을 제공합니다 deliver
. 둘 다 사용하지 future
않거나 delay
사용 사례와 일치 할 때 사용합니다 .
첫째, a Promise
는 Future
. 나는 당신이 a Promise
와 a 의 차이점을 알고 싶다고 생각합니다 FutureTask
.
A Future
는 현재 알려지지 않았지만 앞으로 알려질 값을 나타냅니다.
A FutureTask
는 미래에 발생할 계산의 결과를 나타냅니다 (일부 스레드 풀에서). 결과에 액세스하려고 할 때 계산이 아직 발생하지 않으면 차단됩니다. 그렇지 않으면 결과가 즉시 반환됩니다. 계산은 귀하가 미리 지정하므로 결과 계산에 관여하는 다른 당사자가 없습니다.
A Promise
는 약속자가 향후 약속 자에게 전달할 결과를 나타냅니다. 이 경우에 당신은 약속 자이고 약속자는 당신에게 Promise
물건 을 준 사람 입니다. 와 유사하게 FutureTask
,가 처리되기 전에 결과에 액세스하려고 Promise
하면 약속자가 Promise
. 일단 Promise
충족 되면 항상 동일한 가치를 얻습니다. 와 달리 FutureTask
여기에 다른 당사자가 참여하여 Promise
. 다른 당사자는 계산을 수행하고 Promise
.
그런 의미에서 a FutureTask
는 Promise
당신이 만든 것입니다.