需要确认一些事情。以下代码:
CompletableFuture
.supplyAsync(() -> {return doSomethingAndReturnA();})
.thenApply(a -> convertToB(a));
将与以下相同:
CompletableFuture
.supplyAsync(() -> {
A a = doSomethingAndReturnA();
convertToB(a);
});
右?
此外,接下来的另外两个问题是“我们有什么理由使用 thenApply
?
1) 有转换的大代码吗?
或
2)需要在其他地方重用lambda块?
thenApply()
是一个回调函数,当 supplyAsync()
返回一个值时,将执行该函数。
在代码片段2中,调用< code > doSomethingAndReturnA()的线程等待函数执行并返回数据。
但是在一些异常情况下(比如调用Webservice和等待响应),线程需要等待很长时间才能得到响应,这严重消耗了大量的系统计算资源(仅仅是等待响应)。
为了避免这种情况,CompletableFuture
带有回调功能,一旦调用doThingAndRecnA()
,一个单独的线程将负责执行doThingAndRecnA()
,并且主调用者线程将继续执行其他操作,而无需等待响应返回。
一旦doThingAndRecnA
的响应可用,将调用回调方法(即thenApply()
)
这不是一回事。在第二个示例中,如果不使用<code>thenappy
但是,在第一个示例中,当使用< code>thenApply方法时,可能会发生其他情况。
首先,如果执行<code>doSomething和Returna<code>的<code>CompletableFuture</code>已经完成,调用<code>然后应用<code>将在调用线程中发生。如果<code>CompletableFutures
困惑?这篇文章可能会有所帮助(感谢@SotiriosDimanolis的链接)。
我提供了一个简短的例子来说明thenApply
是如何工作的。
public class CompletableTest {
public static void main(String... args) throws ExecutionException, InterruptedException {
final CompletableFuture<Integer> future = CompletableFuture
.supplyAsync(() -> doSomethingAndReturnA())
.thenApply(a -> convertToB(a));
future.get();
}
private static int convertToB(final String a) {
System.out.println("convertToB: " + Thread.currentThread().getName());
return Integer.parseInt(a);
}
private static String doSomethingAndReturnA() {
System.out.println("doSomethingAndReturnA: " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "1";
}
}
输出为:
doSomethingAndReturnA: ForkJoinPool.commonPool-worker-1
convertToB: ForkJoinPool.commonPool-worker-1
因此,当第一个操作很慢时(即CompletableFuture
尚未完成),两个调用都发生在同一个线程中。但是如果我们要删除<code>线程。sleep-从<code>DoSomething和Returna</code>调用输出(可能)如下:
doSomethingAndReturnA: ForkJoinPool.commonPool-worker-1
convertToB: main
请注意,转换ToB
调用位于main
线程中。
我正在java8中尝试: 运行时,我得到以下输出: 是否需要“错误”信息?我的代码片段中有没有遗漏什么?
要并行或异步运行一些东西,我可以使用ExecutorService:
我正在实施重试策略。基本上,我想做的是在一个单独的线程上重试POST请求。我在用杰曼的故障保护(https://github.com/jhalterman/failsafe#asynchronous-api集成)这是我的代码 我不想抓住这里的例外。它由重试策略处理。目前不会重试,因为我在这里捕获了异常。是否有方法从“SupplySync”引发异常,以便由重试策略处理?谢谢谢谢
我正在尝试实现一个通用的REST客户端,如下所示。我有自己的模型将HTTP响应表示为response T。这里T是服务调用的返回类型,它可能只是T或Ts列表。下面的代码不编译,我需要帮助。 最终调用下面的方法,
在Java 8中引入了CompletableFuture类来表示Future,可以通过设置其值和状态明确来完成。 它可以用作java.util.concurrent.CompletionStage。 它支持在未来完成时触发的依赖功能和操作。 在java 9中,CompletableFuture API得到了进一步的增强。 以下是对API进行的相关更改。 支持延迟和超时。 Improved supp
问题内容: 我刚刚开始探索Java 8的一些并发特性。让我有些困惑的是这两个静态方法: 有谁知道为什么选择使用界面供应商?使用Callable是否更自然,这类似于Runnable返回值?那是因为供应商没有抛出无法处理的异常吗? 问题答案: 简短答案 不,用代替in 是不自然的。该论点几乎完全是关于语义的,因此,如果您此后仍不确信,那就可以了。 长答案 的和功能接口/ SAM类型在功能几乎等同(原谅