【问题标题】:Waiting for callback for multiple futures等待多个期货的回调
【发布时间】:2013-12-10 18:25:57
【问题描述】:

最近我深入研究了一些使用 API 的工作。该 API 使用 Unirest http 库来简化从 Web 接收的工作。自然,由于数据是从 API 服务器调用的,因此我尝试通过对 API 进行异步调用来提高效率。我的想法结构如下:

  1. 通过返回期货结果创建数据数组
  2. 显示数据 + 从数据中收集的其他信息

因此,我需要在开始第二步之前返回所有数据。我的代码如下:

Future < HttpResponse < JsonNode >  > future1 = Unirest.get("https://example.com/api").asJsonAsync(new Callback < JsonNode > () {
    public void failed(UnirestException e) {
        System.out.println("The request has failed");
    }
    public void completed(HttpResponse < JsonNode > response) {
        System.out.println(response.getBody().toString());
        responses.put(response);
    }
    public void cancelled() {
        System.out.println("The request has been cancelled");
    }
});
Future < HttpResponse < JsonNode >  > future2 = Unirest.get("https://example.com/api").asJsonAsync(new Callback < JsonNode > () {
    public void failed(UnirestException e) {
        System.out.println("The request has failed");
    }
    public void completed(HttpResponse < JsonNode > response) {
        System.out.println(response.getBody().toString());
        responses.put(response);
    }
    public void cancelled() {
        System.out.println("The request has been cancelled");
    }
});
doStuff(responses);

我将如何做到只有在两个期货都完成后才调用 doStuff?

【问题讨论】:

标签: java api concurrency future


【解决方案1】:

有几个选项。您现在拥有的代码从您提出请求的同一线程调用doStuff。如果您想阻塞直到两个请求都完成,您可以使用 CountDownLatch。比如:

CountDownLatch responseWaiter = new CountDownLatch(2);

Future <HttpResponse<JsonNode>> future1 = Unirest.get("https://example.com/api").asJsonAsync(new Callback<JsonNode>() {
  public void completed(HttpResponse<JsonNode> response) {
    responses.put(response);
    responseWaiter.countDown();
  }
  ...
});

// Similar code for the other get call
...

responseWaiter.await();
doStuff(responses);

如果您不想在两个调用都完成之前阻塞该线程,您可以让每个匿名内部回调类增加一个 AtomicInteger。当计数为 2 时,您将调用 doStuff。比如:

AtomicInteger numCompleted = new AtomicInteger();

Future <HttpResponse<JsonNode>> future1 = Unirest.get("https://example.com/api").asJsonAsync(new Callback<JsonNode>() {
  public void completed(HttpResponse<JsonNode> response) {
    responses.put(response);
    int numDone = numCompleted.incrementAndGet();
    if (numDone == 2) {
      doStuff(responses);
    }
  }
});

【讨论】:

    猜你喜欢
    • 2013-07-14
    • 2020-10-31
    • 2019-10-29
    • 2017-12-15
    • 1970-01-01
    • 2020-07-21
    • 2015-05-30
    • 2020-06-12
    • 2015-06-03
    相关资源
    最近更新 更多