Tanto os futuros quanto as promessas se bloqueiam até que tenham calculado seus valores, então qual é a diferença entre eles?
clojure
terminology
future
promise
appshare.co
fonte
fonte
Respostas:
Respondendo em termos de Clojure, aqui estão alguns exemplos do screencast de Sean Devlin :
Observe que, na promessa, você está entregando explicitamente um valor que selecionou em um cálculo posterior (
:fred
neste caso). O futuro, por outro lado, está sendo consumido no mesmo lugar em que foi criado. Osome-expr
é presumivelmente lançado nos bastidores e calculado em conjunto (eventualmente), mas se permanecer sem avaliação no momento em que for acessado, o thread bloqueia até que esteja disponível.editado para adicionar
Para ajudar a distinguir ainda mais entre uma promessa e um futuro, observe o seguinte:
promessa
promise
. Esse objeto de promessa agora pode ser passado para qualquer thread.deliver
enviar os resultados para esse objeto de promessa.deref
cumprir sua promessa antes de terminar o cálculo será bloqueado até que você termine. Depois de terminar edeliver
cumprir a promessa, a promessa não bloqueará mais.futuro
deref
é o futuro. Se o cálculo já foi concluído, você obtém os resultados dele. Se ainda não foi concluído, você bloqueia até que seja concluído. (Provavelmente, se ainda não começou,deref
significa que começou a ser executado, mas isso também não é garantido.)Embora você possa tornar a expressão no futuro tão complicada quanto o código que segue a criação de uma promessa, é duvidoso que isso seja desejável. Isso significa que os futuros são realmente mais adequados para cálculos rápidos e em segundo plano, enquanto as promessas são realmente mais adequadas para caminhos de execução grandes e complicados. Também, as promessas parecem, em termos de cálculos disponíveis, um pouco mais flexíveis e orientadas para o criador da promessa fazendo o trabalho e outro fio colhendo a colheita. Os futuros são mais orientados para iniciar automaticamente um thread (sem a sobrecarga feia e propensa a erros) e continuar com outras coisas até que você - o thread de origem - precise dos resultados.
fonte
future
chamada pode incluir N sexprs.Futuro e Promessa são mecanismos para comunicar o resultado da computação assíncrona do produtor para o (s) consumidor (es).
No caso de Future, o cálculo é definido no momento da criação do Future e a execução assíncrona começa "ASAP". Ele também "sabe" como gerar uma computação assíncrona.
No caso do Promise, o cálculo , sua hora de início e [possível] chamada assíncrona são desacoplados do mecanismo de entrega. Quando o resultado do cálculo está disponível, o Produtor deve chamar
deliver
explicitamente, o que também significa que o Produtor controla quando o resultado fica disponível.For Promises Clojure comete um erro de design ao usar o mesmo objeto (resultado da
promise
chamada) para produzir (deliver
) e consumir (deref
) o resultado da computação . Esses são dois recursos muito distintos e devem ser tratados como tal.fonte
promise
seria conveniente. Consumidores 'maus' são raros; nada o impede de construir sua própria abstração em cima de promessas.(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))))
Já existem respostas excelentes, então apenas adicionando o resumo "como usar":
Ambos
Criar promessa ou futuro retorna uma referência imediatamente. Esta referência bloqueia em @ / deref até que o resultado do cálculo seja fornecido por outro thread.
Futuro
Ao criar o futuro, você fornece um trabalho síncrono a ser feito. É executado em um thread do pool ilimitado dedicado.
Promessa
Você não dá argumentos ao criar promessa. A referência deve ser passada para outro encadeamento de 'usuário' que será
deliver
o resultado.fonte
Em Clojure,
promise
,future
, edelay
são promessa semelhante objetos. Todos eles representam uma computação que os clientes podem esperar usandoderef
(ou@
). Os clientes reutilizam o resultado, para que o cálculo não seja executado várias vezes.Eles diferem na forma como o cálculo é realizado:
future
irá iniciar o cálculo em um thread de trabalho diferente.deref
irá bloquear até que o resultado esteja pronto.delay
executará o cálculo preguiçosamente, quando o primeiro cliente usarderef
, ouforce
.promise
oferece mais flexibilidade, pois seu resultado é fornecido de qualquer forma personalizada usandodeliver
. Você o usa quando nenhumfuture
oudelay
corresponde ao seu caso de uso.fonte
Em primeiro lugar, a
Promise
é aFuture
. Acho que você quer saber a diferença entre aPromise
e aFutureTask
.A
Future
representa um valor que não é conhecido atualmente, mas será conhecido no futuro.A
FutureTask
representa o resultado de um cálculo que acontecerá no futuro (talvez em algum pool de threads). Quando você tenta acessar o resultado, se o cálculo ainda não aconteceu, ele bloqueia. Caso contrário, o resultado é retornado imediatamente. Não há nenhuma outra parte envolvida no cálculo do resultado, pois o cálculo é especificado por você antecipadamente.A
Promise
representa um resultado que será entregue pelo prometente ao prometido no futuro. Nesse caso, você é o prometido e o prometedor é aquele que lhe deu oPromise
objeto. Semelhante aoFutureTask
, se você tentar acessar o resultado antes dePromise
ter sido cumprido, ele será bloqueado até que o prometente cumpra oPromise
. Assim que oPromise
for cumprido, você obterá o mesmo valor sempre e imediatamente. Ao contrário de umFutureTask
, há uma outra parte envolvida aqui, aquela que fez oPromise
. Essa outra parte é responsável por fazer o cálculo e cumprir oPromise
.Nesse sentido, a
FutureTask
é um quePromise
você fez para si mesmo.fonte