未来和承诺的区别是什么? 它们都像未来结果的占位符,但主要的区别在哪里?
当前回答
我将给出一个例子,说明什么是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);
它的输出是:
Thank you mom for $10
妈妈的承诺被创造出来了,但等待着一些“完成”的事件。
CompletableFuture<Integer> promise...
你创造了这样一个活动,接受她的承诺,并宣布你的计划来感谢你的妈妈:
promise.thenAccept...
就在这时,妈妈开始打开她的钱包……但是非常慢……
父亲比你妈妈更快地完成了承诺:
promise.complete(10);
你注意到我明确写的一个执行者了吗?
有趣的是,如果您使用默认的隐式执行器(commonPool),并且父亲不在家,而只有母亲带着她的“慢钱包”,那么她的承诺只有在程序存活的时间比母亲从钱包中获取资金所需的时间长时才会完成。
默认执行程序的行为有点像“守护进程”,并不等待所有的承诺被履行。我还没有找到一个很好的描述这个事实的词……
其他回答
未来vs承诺
未来和承诺是未知结果的代理对象
承诺成就未来
承诺-写/制作人未知的结果。 未知结果的未来读取/消费者。它有接下来的状态:待处理、完成、取消
//Future has a reference to Promise
Future -> Promise
作为制作人,我承诺一些事情并为此负责
作为一个收回承诺的消费者,我希望在未来有一个结果。将来我可以使用这个承诺,也可以拒绝它
至于Java的CompletableFutures,它是一个Promise,因为你可以设置结果,而且它实现了Future
在这个例子中,您可以看看如何在Java中使用Promises 用于创建异步调用序列:
doSomeProcess()
.whenResult(result -> System.out.println(String.format("Result of some process is '%s'", result)))
.whenException(e -> System.out.println(String.format("Exception after some process is '%s'", e.getMessage())))
.map(String::toLowerCase)
.mapEx((result, e) -> e == null ? String.format("The mapped result is '%s'", result) : e.getMessage())
.whenResult(s -> System.out.println(s));
我知道已经有了一个公认的答案,但我仍然想补充我的意见:
TLDR:未来和承诺是异步操作的两个方面:消费者/调用者vs.生产者/实现者。
作为异步API方法的调用者,您将获得一个Future作为计算结果的句柄。例如,你可以对它调用get()来等待计算完成并检索结果。
现在想想这个API方法实际上是如何实现的:实现者必须立即返回一个Future。它们负责在计算完成后立即完成该future(它们将知道这一点,因为它正在实现分派逻辑;-))。它们将使用Promise/CompletableFuture来完成:立即构造并返回CompletableFuture,并在计算完成后调用complete(T result)。
我将给出一个例子,说明什么是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);
它的输出是:
Thank you mom for $10
妈妈的承诺被创造出来了,但等待着一些“完成”的事件。
CompletableFuture<Integer> promise...
你创造了这样一个活动,接受她的承诺,并宣布你的计划来感谢你的妈妈:
promise.thenAccept...
就在这时,妈妈开始打开她的钱包……但是非常慢……
父亲比你妈妈更快地完成了承诺:
promise.complete(10);
你注意到我明确写的一个执行者了吗?
有趣的是,如果您使用默认的隐式执行器(commonPool),并且父亲不在家,而只有母亲带着她的“慢钱包”,那么她的承诺只有在程序存活的时间比母亲从钱包中获取资金所需的时间长时才会完成。
默认执行程序的行为有点像“守护进程”,并不等待所有的承诺被履行。我还没有找到一个很好的描述这个事实的词……
根据上述讨论,Promise最终被命名为CompletableFuture以包含在Java 8中,它的javadoc解释说:
一个可以显式完成的Future(设置其值和状态),并且可以用作CompletionStage,支持在其完成时触发的依赖函数和操作。
列表中还给出了一个例子:
f.then((s -> aStringFunction(s)).thenAsync(s -> ...);
注意,最终的API略有不同,但允许类似的异步执行:
CompletableFuture<String> f = ...;
f.thenApply(this::modifyString).thenAccept(System.out::println);
推荐文章
- Intellij IDEA Java类在保存时不能自动编译
- 何时使用Mockito.verify()?
- 在maven中安装mvn到底做什么
- 不可变与不可修改的集合
- 如何在JSON中使用杰克逊更改字段名
- GSON -日期格式
- 如何从线程捕获异常
- 无法解析主机"<URL here>"没有与主机名关联的地址
- 如何在Java中打印二叉树图?
- String.format()在Java中格式化双重格式
- com.jcraft.jsch.JSchException: UnknownHostKey
- Java中的操作符重载
- 如何加速gwt编译器?
- 在Hibernate中重新连接分离对象的正确方法是什么?
- 应该……接住环内还是环外?