gpt4 book ai didi

java - Java异步HttpClient请求似乎阻塞了主线程?

转载 作者:行者123 更新时间:2023-12-03 13:18:32 28 4
gpt4 key购买 nike

根据this,以下代码段应为Async。
因此,输出应显示为:TP1,TP2,TP3,http://openjdk.java.net/
但是,当我运行它时,我得到:TP1,TP2,http://openjdk.java.net/,TP3。
似乎“sendAsync”正在阻止主线程。这不是我从异步方法中获得的期望。
难道我做错了什么?

 public static void main(String[] args) {

HttpClient client = HttpClient.newHttpClient();

System.out.println("TP1");

HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://openjdk.java.net/"))
.build();

System.out.println("TP2");

client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::uri)
.thenAccept(System.out::println)
.join();

System.out.println("TP3");

}

最佳答案

解释
您调用join(),它将显式等待并阻塞,直到将来完成。
CompletableFuture#join:

Returns the result value when complete, or throws an (unchecked) exception if completed exceptionally. [...]


尽管没有明确提及,但从名称上可以明显看出(请参阅 Thread#join,“等待该线程死亡。”),它只能通过等待调用完成来返回结果。
该方法与 CompletableFuture#get非常相似,它们在异常完成方面的行为有所不同:

Waits if necessary for this future to complete, and then returns its result.



解决方案
在实际需要等待时,将future放入变量中,然后再加入。
例如:
System.out.println("TP2");

var task = client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::uri)
.thenAccept(System.out::println);

System.out.println("TP3");

task.join(); // wait later
或永远不要等待。然后,您的主线程可能会更早死掉,但是只有在所有非守护程序线程都死了并且 HttpClient用于异步任务的线程不是守护程序线程之后,JVM才会关闭。

笔记
而且,永远不要依赖多线程执行的顺序。
即使您不会犯错,您观察到的顺序也会是多线程执行的 有效顺序
请记住,OS调度程序可以自由决定以什么顺序执行什么-它可以是任何顺序。

关于java - Java异步HttpClient请求似乎阻塞了主线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63998918/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com