首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用AsyncRestTemplate同时进行多个呼叫?

如何使用AsyncRestTemplate同时进行多个呼叫?
EN

Stack Overflow用户
提问于 2016-02-05 00:38:31
回答 6查看 25.3K关注 0票数 20

我不明白如何有效地使用AsyncRestTemplate进行外部服务调用。关于以下代码:

代码语言:javascript
复制
class Foo {

    public void doStuff() {
        Future<ResponseEntity<String>> future1 = asyncRestTemplate.getForEntity(
                url1, String.class);
        String response1 = future1.get();

        Future<ResponseEntity<String>> future2 = asyncRestTemplate.getForEntity(
                url2, String.class);
        String response2 = future2.get();

        Future<ResponseEntity<String>> future3 = asyncRestTemplate.getForEntity(
                url3, String.class);
        String response3 = future3.get();
    }
}

理想情况下,我希望同时执行所有3个调用,并在它们都完成后处理结果。然而,,每个外部服务调用都是,而不是,直到get()被调用,但get()被阻塞。那么,这难道不辜负AsyncRestTemplate的目的吗?我还是用RestTemplate吧。

所以我不明白怎么才能让他们同时执行?

EN

回答 6

Stack Overflow用户

发布于 2016-02-09 13:25:33

只需在分派所有异步调用之前,不要调用阻塞get()

代码语言:javascript
复制
class Foo {
  public void doStuff() {
    ListenableFuture<ResponseEntity<String>> future1 = asyncRestTemplate
        .getForEntity(url1, String.class);
    ListenableFuture<ResponseEntity<String>> future2 = asyncRestTemplate
        .getForEntity(url2, String.class);
    ListenableFuture<ResponseEntity<String>> future3 = asyncRestTemplate
        .getForEntity(url3, String.class);

    String response1 = future1.get();
    String response2 = future2.get();
    String response3 = future3.get();
  }
}

您可以在循环中执行分派 get ,但请注意,当前的结果收集效率很低,因为它将被困在下一个未完成的未来。

您可以将所有的期货添加到一个集合中,并遍历它,测试每个未来的非阻塞isDone()。当该调用返回true时,您可以调用get()

这样,您的整体结果收集将被优化,而不是按照调用get()的顺序等待下一个缓慢的未来结果。

更好的是,您可以在每个由ListenableFuture返回的AccyncRestTemplate中注册回调(运行时),而不必担心周期性地检查潜在的结果。

票数 17
EN

Stack Overflow用户

发布于 2016-02-10 15:34:09

如果你不用使用'AsyncRestTemplate‘,我建议你用RxJava代替。RxJava zip操作符是您要找的。检查下面的代码:

代码语言:javascript
复制
private rx.Observable<String> externalCall(String url, int delayMilliseconds) {
    return rx.Observable.create(
            subscriber -> {
                try {
                    Thread.sleep(delayMilliseconds); //simulate long operation
                    subscriber.onNext("response(" + url + ") ");
                    subscriber.onCompleted();
                } catch (InterruptedException e) {
                    subscriber.onError(e);
                }
            }
    );
}

public void callServices() {
    rx.Observable<String> call1 = externalCall("url1", 1000).subscribeOn(Schedulers.newThread());
    rx.Observable<String> call2 = externalCall("url2", 4000).subscribeOn(Schedulers.newThread());
    rx.Observable<String> call3 = externalCall("url3", 5000).subscribeOn(Schedulers.newThread());
    rx.Observable.zip(call1, call2, call3, (resp1, resp2, resp3) -> resp1 + resp2 + resp3)
            .subscribeOn(Schedulers.newThread())
            .subscribe(response -> System.out.println("done with: " + response));
}

所有对外部服务的请求都将在单独的线程中执行,当最后一次调用完成时,转换函数(例如简单的字符串连接)将被应用,结果(连接的字符串)将从'zip‘发出。

票数 8
EN

Stack Overflow用户

发布于 2016-02-12 11:17:26

我从您的问题中了解到的是,您有一个预定义的异步方法,并且尝试使用RestTemplate类异步调用该方法。

我已经编写了一个方法,它将帮助您异步调用您的方法。

代码语言:javascript
复制
 public void testMyAsynchronousMethod(String... args) throws Exception {
        // Start the clock
        long start = System.currentTimeMillis();

        // Kick of multiple, asynchronous lookups
        Future<String> future1 = asyncRestTemplate
        .getForEntity(url1, String.class);;
        Future<String> future2 = asyncRestTemplate
        .getForEntity(url2, String.class);
        Future<String> future3 = asyncRestTemplate
        .getForEntity(url3, String.class);

        // Wait until they are all done
        while (!(future1 .isDone() && future2.isDone() && future3.isDone())) {
            Thread.sleep(10); //10-millisecond pause between each check
        }

        // Print results, including elapsed time
        System.out.println("Elapsed time: " + (System.currentTimeMillis() - start));
        System.out.println(future1.get());
        System.out.println(future2.get());
        System.out.println(future3.get());
    }
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35214384

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档