如果线程终止太早,则使用 httpClient.sendAsync(...) 不要发送请求

问题描述 投票:0回答:1

我正在使用 java.net.http.HttpClient 发送一些请求并忽略响应,但是当我尝试测试时,我注意到如果我不稍等一下,请求就不会发送。

我有一个非常简单的方法:

public CompletableFuture<HttpResponse<String>> getAsyncHttp(final String url) {
    HttpClient httpClient = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(url))
            .build();
    System.out.println("Send request : " + url);
    return httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString());
}

我这样称呼:

private static void callRequest(){
    HttpAsyncRequest httpAsyncRequest = new HttpAsyncRequest();
    String URL = "http://localhost:3000/test";
    httpAsyncRequest.getAsyncHttp(URL);
    System.out.println("Request done.");
    // we exit here basically
}

我只是尝试发送http请求并故意忽略响应,但请求并未发送。

但是,如果更改我的 callRequest() 方法并添加线程睡眠

private static void callRequest() throws InterruptedException {
    HttpAsyncRequest httpAsyncRequest = new HttpAsyncRequest();
    String URL = "http://localhost:3000/test";
    httpAsyncRequest.getAsyncHttp(URL);
    Thread.sleep(100); // line added
    System.out.println("Request done.");
    // we exit here basically
}

现在请求已发送,但当我不等待服务器时,非常需要添加线程睡眠,因为我只是发送请求。

人们可以重现此问题或愿意解释为什么会发生吗?

谢谢你。

java http asynchronous
1个回答
0
投票

调用是异步的。这意味着它独立于其调用线程执行。除非您收到已完成的通知,否则您不知道它已“完成”。

获取通知正是“sendAsync”调用返回 Future 的原因。在 callRequest 方法中等待 Future(例如,通过“get”),不要忽略它。

我读到您不需要响应,但是您选择使用的 API 无法知道请求甚至已经离开本地系统,更不用说到达远程服务器了。如果没有某种响应,您就无法知道服务器是否以及何时看到该请求;这是不可知的。 (在 TCP 级别,ack 仅意味着它已到达远程 TCP 堆栈)。因此,等待响应是使其可靠的唯一方法。

CompleteableFuture 文档

© www.soinside.com 2019 - 2024. All rights reserved.