use*_*330 241 java concurrency future promise
Future和之间有什么区别Promise?
它们都像未来结果的占位符,但主要区别在哪里?
ass*_*ias 130
根据这个讨论,Promise最终被要求CompletableFuture包含在Java 8中,它的javadoc解释说:
可以显式完成的Future(设置其值和状态),并且可以用作CompletionStage,支持在完成时触发的依赖函数和操作.
列表中还给出了一个示例:
f.then((s -> aStringFunction(s)).thenAsync(s -> ...);
Run Code Online (Sandbox Code Playgroud)
请注意,最终的API略有不同,但允许类似的异步执行:
CompletableFuture<String> f = ...;
f.thenApply(this::modifyString).thenAccept(System.out::println);
Run Code Online (Sandbox Code Playgroud)
lba*_*scs 130
(到目前为止,我对答案并不完全满意,所以这是我的尝试......)
我认为凯文赖特的评论("你可以做出承诺,并由你来保留它.当别人让你做出承诺时,你必须等待他们是否在未来尊重它")总结得很好,但有些解释可能很有用.
期货和承诺是非常相似的概念,不同之处在于,未来是一个尚未存在的结果的只读容器,而承诺可以写入(通常只有一次).Java 8 CompletableFuture和Guava SettableFuture可以被认为是promises,因为它们的值可以设置("完成"),但它们也实现了Future接口,因此客户端没有区别.
未来的结果将由"其他人"设置 - 通过异步计算的结果.注意FutureTask - 一个经典的未来 - 必须用Callable或Runnable初始化,没有无参构造函数,Future和FutureTask都是从外部读取的(FutureTask的set方法受到保护).该值将从内部设置为计算结果.
另一方面,承诺的结果可以随时由"你"(或实际上由任何人)设置,因为它具有公共setter方法.CompletableFuture和SettableFuture都可以在没有任何任务的情况下创建,并且可以随时设置它们的值.您向客户端代码发送承诺,并在以后按照您的意愿完成.
请注意,CompletableFuture不是一个"纯"的承诺,它可以像FutureTask一样使用任务进行初始化,其最有用的功能是处理步骤的无关链接.
另请注意,promise不必是future的子类型,也不必是同一个对象.在Scala中,Future对象由异步计算或不同的 Promise对象创建.在C++中,情况类似:生产者使用promise对象,消费者使用future对象.这种分离的好处是客户端无法设置未来的价值.
两个弹簧和EJB 3.1具有AsyncResult类,它是类似于斯卡拉/ C++承诺.AsyncResult确实实现了Future,但这不是真正的未来:Spring/EJB中的异步方法通过一些背景魔法返回一个不同的只读Future对象,客户端可以使用第二个"真实"未来来访问结果.
Rah*_*thy 103
我知道已经有一个已接受的答案,但我想加上我的两分钱:
TLDR:Future和Promise是异步操作的两个方面:消费者/调用者与生产者/实现者.
作为异步API方法的调用者,您将获得Future计算结果的句柄.您可以调用get()它来等待计算完成并检索结果.
现在想一想这个API方法是如何实现的:实现者必须Future立即返回.一旦计算完成,他们就负责完成未来(他们知道因为它正在实施调度逻辑;-)).他们将使用Promise/ CompletableFuture来做到这一点:构造并CompletableFuture立即返回,并complete(T result)在计算完成后调用.
Vla*_*kov 58
我将举例说明什么是Promise以及如何在任何时候设置其值,与Future相反,该值只能读取.
假设你有一个妈妈,你问她要钱.
现在,你欺骗你的妈妈为你创造一个最终捐赠的承诺,她给你这个承诺对象,但她还没有真正轻率地实现它:
// Now , you trick your mom into creating you a promise of eventual
// donation, she gives you that promise object, but she is not really
// in rush to fulfill it yet:
Supplier<Integer> momsPurse = ()-> {
try {
Thread.sleep(1000);//mom is busy
} catch (InterruptedException e) {
;
}
return 100;
};
ExecutorService ex = Executors.newFixedThreadPool(10);
CompletableFuture<Integer> promise =
CompletableFuture.supplyAsync(momsPurse, ex);
// You are happy, you run to thank you your mom:
promise.thenAccept(u->System.out.println("Thank you mom for $" + u ));
// But your father interferes and generally aborts mom's plans and
// completes the promise (sets its value!) with far lesser contribution,
// as fathers do, very resolutely, while mom is slowly opening her purse
// (remember the Thread.sleep(...)) :
promise.complete(10);
Run Code Online (Sandbox Code Playgroud)
你很高兴,你要感谢你的妈妈:
Thank you mom for $10
Run Code Online (Sandbox Code Playgroud)
但是你的父亲干涉并且通常会中止妈妈的计划并完成承诺(设定其价值!)的贡献要小得多,正如父亲那样,非常坚决,而妈妈正在慢慢打开她的钱包(注意Thread.sleep(...)):
CompletableFuture<Integer> promise...
Run Code Online (Sandbox Code Playgroud)
输出是:
promise.thenAccept...
Run Code Online (Sandbox Code Playgroud)
妈妈的承诺已经创建,但等待一些"完成"事件.
promise.complete(10);
Run Code Online (Sandbox Code Playgroud)
你创建了这样的活动,接受了她的承诺,并宣布你的计划,感谢你的妈妈:
// Now , you trick your mom into creating you a promise of eventual
// donation, she gives you that promise object, but she is not really
// in rush to fulfill it yet:
Supplier<Integer> momsPurse = ()-> {
try {
Thread.sleep(1000);//mom is busy
} catch (InterruptedException e) {
;
}
return 100;
};
ExecutorService ex = Executors.newFixedThreadPool(10);
CompletableFuture<Integer> promise =
CompletableFuture.supplyAsync(momsPurse, ex);
// You are happy, you run to thank you your mom:
promise.thenAccept(u->System.out.println("Thank you mom for $" + u ));
// But your father interferes and generally aborts mom's plans and
// completes the promise (sets its value!) with far lesser contribution,
// as fathers do, very resolutely, while mom is slowly opening her purse
// (remember the Thread.sleep(...)) :
promise.complete(10);
Run Code Online (Sandbox Code Playgroud)
这时妈妈开始打开她的钱包......但很慢......
和父亲干涉得更快,完成了承诺,而不是你的妈妈:
Thank you mom for $10
Run Code Online (Sandbox Code Playgroud)
您是否注意到我明确写过的执行人?有趣的是,如果你使用默认的隐式执行器(commonPool)而父亲不在家,只有妈妈带着她的"慢钱包",那么她的承诺只会完成,如果程序的生命时间超过妈妈需要的钱钱包.我的意思是默认执行程序以"守护进程"的方式运行.我没有找到这个事实的好描述......
不确定这是否可以作为答案但是当我看到其他人对某人所说的内容时,您可能看起来需要对这两个概念进行两个单独的抽象,以便其中一个(Future)只是另一个的只读视图(Promise)...但实际上这不是必需的.
例如,看看如何在javascript中定义promises:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
重点是使用以下then方法的可组合性:
asyncOp1()
.then(function(op1Result){
// do something
return asyncOp2();
})
.then(function(op2Result){
// do something more
return asyncOp3();
})
.then(function(op3Result){
// do something even more
return syncOp4(op3Result);
})
...
.then(function(result){
console.log(result);
})
.catch(function(error){
console.log(error);
})
Run Code Online (Sandbox Code Playgroud)
这使异步计算看起来像同步:
try {
op1Result = syncOp1();
// do something
op1Result = syncOp2();
// do something more
op3Result = syncOp3();
// do something even more
syncOp4(op3Result);
...
console.log(result);
} catch(error) {
console.log(error);
}
Run Code Online (Sandbox Code Playgroud)
这很酷.(不像async-await那样酷,但async-await只是删除样板....然后(函数(结果){....从它).
实际上,他们的抽象作为promise构造函数非常好
new Promise( function(resolve, reject) { /* do it */ } );
Run Code Online (Sandbox Code Playgroud)
允许您提供两个回调,可用于Promise成功完成或出错.因此,只有构造Promise它的代码才能完成它,并且接收已构造Promise对象的代码具有只读视图.
通过继承,如果解析和拒绝是受保护的方法,则可以实现上述目的.
小智 5
对于客户端代码,Promise 用于在结果可用时观察或附加回调,而 Future 是等待结果然后继续。理论上任何可以用期货做的事情都可以用承诺做的,但由于风格差异,不同语言的承诺的结果 API 使链接更容易。
未来与承诺
Future是Promise未知结果的代理对象
Promise完成一个Future
Promise- 未知结果的写入/生成者。Future- 读取/消费者未知结果。它有以下状态:待定、已完成、已取消//Future has a reference to Promise
Future -> Promise
Run Code Online (Sandbox Code Playgroud)
作为一个producer我promise做某事并对其负责的人
作为一个consumer检索了 a 的人,promise我希望得到一个结果future。在future我可以使用promise或拒绝它
至于Java,CompletableFutures它是一个Promise,因为你可以设置结果并且它也实现Future