CompletableFuture 的 complete 方法的目的是什么?
What is the purpose of CompletableFuture's complete method?
我一直在阅读有关 CompletableFuture 的资料。
到目前为止,我了解到 CompletableFuture 与 Future 的不同之处在于它提供了将 futures 链接在一起的方法,使用回调来处理 Future 的结果而不实际阻塞代码。
但是,我很难理解这个 complete() 方法。我只知道它可以让我们手动完成一个future,但是它有什么用呢?我为这种方法找到的最常见的例子是在执行一些异步任务时,我们可以立即 return 例如一个字符串。但是,如果 return 值没有反映实际结果,那么这样做有什么意义呢?如果我们想异步地做一些事情,为什么我们不直接使用常规的 future 呢?我能想到的唯一用途是当我们想要有条件地取消正在进行的未来时。但我想我在这里遗漏了一些重要的关键点。
complete() 相当于函数对前一阶段的结果进行改造,返回getResponse("a1=Chittagong&a2=city")
响应,你可以运行这个方法在不同的线程
当 getResponse() 方法响应可用时, thenApply() 将被调用以打印日志。
如果您 运行 getResponse(String url) 在不同的线程中,没有人会被阻止。
此示例展示了我们在从 complete() 获取响应时打印日志的场景;
代码
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CompletableFutureEx {
Logger logger = Logger.getLogger(CompletableFutureEx.class.getName());
public static void main(String[] args) {
new CompletableFutureEx().completableFutureEx();
}
private void completableFutureEx() {
var completableFuture = new CompletableFuture<String>();
completableFuture.thenApply(response -> {
logger.log(Level.INFO, "Response : " + response);
return response;
});
//some long process response
try {
completableFuture.complete(getResponse("a1=Chittagong&a2=city"));
} catch (Exception e) {
completableFuture.completeExceptionally(e);
}
try {
System.out.println(completableFuture.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
private String getResponse(String url) throws URISyntaxException, IOException, InterruptedException {
var finalUrl = "http://localhost:8081/api/v1/product/add?" + url;
//http://localhost:8081/api/v1/product/add?a1=Chittagong&a2=city
var request = HttpRequest.newBuilder()
.uri(new URI(finalUrl)).GET().build();
var response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("response body " + response.body());
return response.body();
}
}
我一直在阅读有关 CompletableFuture 的资料。
到目前为止,我了解到 CompletableFuture 与 Future 的不同之处在于它提供了将 futures 链接在一起的方法,使用回调来处理 Future 的结果而不实际阻塞代码。
但是,我很难理解这个 complete() 方法。我只知道它可以让我们手动完成一个future,但是它有什么用呢?我为这种方法找到的最常见的例子是在执行一些异步任务时,我们可以立即 return 例如一个字符串。但是,如果 return 值没有反映实际结果,那么这样做有什么意义呢?如果我们想异步地做一些事情,为什么我们不直接使用常规的 future 呢?我能想到的唯一用途是当我们想要有条件地取消正在进行的未来时。但我想我在这里遗漏了一些重要的关键点。
complete() 相当于函数对前一阶段的结果进行改造,返回getResponse("a1=Chittagong&a2=city") 响应,你可以运行这个方法在不同的线程 当 getResponse() 方法响应可用时, thenApply() 将被调用以打印日志。 如果您 运行 getResponse(String url) 在不同的线程中,没有人会被阻止。
此示例展示了我们在从 complete() 获取响应时打印日志的场景;
代码
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CompletableFutureEx {
Logger logger = Logger.getLogger(CompletableFutureEx.class.getName());
public static void main(String[] args) {
new CompletableFutureEx().completableFutureEx();
}
private void completableFutureEx() {
var completableFuture = new CompletableFuture<String>();
completableFuture.thenApply(response -> {
logger.log(Level.INFO, "Response : " + response);
return response;
});
//some long process response
try {
completableFuture.complete(getResponse("a1=Chittagong&a2=city"));
} catch (Exception e) {
completableFuture.completeExceptionally(e);
}
try {
System.out.println(completableFuture.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
private String getResponse(String url) throws URISyntaxException, IOException, InterruptedException {
var finalUrl = "http://localhost:8081/api/v1/product/add?" + url;
//http://localhost:8081/api/v1/product/add?a1=Chittagong&a2=city
var request = HttpRequest.newBuilder()
.uri(new URI(finalUrl)).GET().build();
var response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("response body " + response.body());
return response.body();
}
}