completeExceptionally 和 obtrudeException 的区别
Difference between completeExceptionally and obtrudeException
刚刚浏览了 CompletableFuture
文档,偶然发现了 completeExceptionally
and obtrudeException
方法,很难理解其中的区别和用例。社区能否通过示例帮助理解差异和用例?
异常完成:
completableFuture.completeExceptionally(
new RuntimeException("Calculation failed!"));
//..
completableFuture.get(); //exception will be thrown whether `completableFuture` was not already completed.
obtrudeException:
completableFuture.obtrudeException(
new RuntimeException("Calculation failed!"));
//..
completableFuture.get(); //exception will be thrown **whether or not** `completableFuture` was completed.
说明
区别很微妙但很重要。来自 official documentation:
If not already completed, causes invocations of get()
and related methods to throw the given exception.
Forcibly causes subsequent invocations of method get()
and related methods to throw the given exception, whether or not already completed. [...]
所以他们在 CompletableFuture
方面的行为不同 已经完成 。
基本上,未来可以是已完成,也可以是待定(未完成)。当您调用 completeExceptionally
或 obtrudeException
时,行为会根据该时间点的未来状态而有所不同。
已经完成的未来
考虑这个例子,在调用方法时 future 已经完成:
CompletableFuture<String> future = CompletableFuture.completedFuture("hello world");
future.completeExceptionally(new RuntimeException("Oh noes!"));
System.out.println(future.get()); // Prints "hello world" just fine
对比
CompletableFuture<String> future = CompletableFuture.completedFuture("hello world");
future.obtrudeException(new RuntimeException("Oh noes!"));
System.out.println(future.get()); // Throws the exception
未完成的未来
如果 future 还没有完成,它们都会抛出异常:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
return "hello world";
});
future.completeExceptionally(new RuntimeException("Oh noes!"));
System.out.println(future.get());
和
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
return "hello world";
});
future.obtrudeException(new RuntimeException("Oh noes!"));
System.out.println(future.get());
complete
和 obtrudeValue
同样,还有一些方法 complete
and obtrudeValue
的行为方式相同,但不是抛出异常,而是提供一个值。
所以complete
基本上是用给定的值完成未来,如果未来还没有完成,否则什么都不做。
虽然 obtrudeValue
无论如何都会提供给定值,因此它会重置或取消任何已经计算的未来,并用给定值替换它。
刚刚浏览了 CompletableFuture
文档,偶然发现了 completeExceptionally
and obtrudeException
方法,很难理解其中的区别和用例。社区能否通过示例帮助理解差异和用例?
异常完成:
completableFuture.completeExceptionally(
new RuntimeException("Calculation failed!"));
//..
completableFuture.get(); //exception will be thrown whether `completableFuture` was not already completed.
obtrudeException:
completableFuture.obtrudeException(
new RuntimeException("Calculation failed!"));
//..
completableFuture.get(); //exception will be thrown **whether or not** `completableFuture` was completed.
说明
区别很微妙但很重要。来自 official documentation:
If not already completed, causes invocations of
get()
and related methods to throw the given exception.
Forcibly causes subsequent invocations of method
get()
and related methods to throw the given exception, whether or not already completed. [...]
所以他们在 CompletableFuture
方面的行为不同 已经完成 。
基本上,未来可以是已完成,也可以是待定(未完成)。当您调用 completeExceptionally
或 obtrudeException
时,行为会根据该时间点的未来状态而有所不同。
已经完成的未来
考虑这个例子,在调用方法时 future 已经完成:
CompletableFuture<String> future = CompletableFuture.completedFuture("hello world");
future.completeExceptionally(new RuntimeException("Oh noes!"));
System.out.println(future.get()); // Prints "hello world" just fine
对比
CompletableFuture<String> future = CompletableFuture.completedFuture("hello world");
future.obtrudeException(new RuntimeException("Oh noes!"));
System.out.println(future.get()); // Throws the exception
未完成的未来
如果 future 还没有完成,它们都会抛出异常:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
return "hello world";
});
future.completeExceptionally(new RuntimeException("Oh noes!"));
System.out.println(future.get());
和
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
return "hello world";
});
future.obtrudeException(new RuntimeException("Oh noes!"));
System.out.println(future.get());
complete
和 obtrudeValue
同样,还有一些方法 complete
and obtrudeValue
的行为方式相同,但不是抛出异常,而是提供一个值。
所以complete
基本上是用给定的值完成未来,如果未来还没有完成,否则什么都不做。
虽然 obtrudeValue
无论如何都会提供给定值,因此它会重置或取消任何已经计算的未来,并用给定值替换它。