我正在使用Spring 4.2.3 AsyncRestTemplate.exchange()来调用一些API,这将花费几秒钟,并且我希望listenableFuture.get(1,TimeUnit.SECONDS)将阻塞1秒钟,然后抛出TimeOutException。

相反,发生的是listenableFuture.get()将在api调用的整个时间(超过1秒)内阻塞

    AsyncRestTemplate restTemplate = new AsyncRestTemplate();

    ListenableFuture<ResponseEntity<String>> listenableFuture = restTemplate.exchange(URL, HttpMethod.GET, null, String.class);
    log.debug("before callback");

    //...add callbacks

    try{
        log.debug("before blocking");
        listenableFuture.get(1, TimeUnit.SECONDS);
    }catch (InterruptedException e) {
        log.error(":GOT InterruptedException");
    } catch (ExecutionException e) {
        log.error(":GOT ExecutionException");
    } catch (TimeoutException e) {
        log.info(":GOT TimeoutException");
    }

    log.info("FINISHED");

输出:
    09:15:21.596  DEBUG [main] org.springframework.web.client.AsyncRestTemplate:78 - Created asynchronous GET request for "http://localhost:4567/oia/wait?seconds=5"
    09:15:21.666  DEBUG [main] org.springframework.web.client.RestTemplate:720 - Setting request Accept header to [text/plain, application/xml, text/xml, application/json, application/*+xml, application/*+json, */*]
    09:15:21.679  DEBUG [main] com.zazma.flow.utils.FutureTest:74 - before callback
    09:15:21.679  DEBUG [main] com.zazma.flow.utils.FutureTest:95 - before blocking
    09:15:26.709  DEBUG [main] org.springframework.web.client.AsyncRestTemplate:576 - Async GET request for "http://localhost:4567/oia/wait?seconds=5" resulted in 200 (OK)
    09:15:26.711  DEBUG [main] org.springframework.web.client.RestTemplate:101 - Reading [java.lang.String] as "text/html;charset=utf-8" using [org.springframework.http.converter.StringHttpMessageConverter@3a44431a]
    09:15:26.717   INFO [main] com.zazma.flow.utils.FutureTest:105 - FINISHED

这是一个示例,当不由AsyncRestTemplate创建时,ListenableFuture.get()将按预期工作
SimpleAsyncTaskExecutor te = new SimpleAsyncTaskExecutor();
    ListenableFuture<String> lf = te.submitListenable(() -> {
        Thread.sleep(8000);
        return "OK";
    });

    lf.get(1, TimeUnit.SECONDS);

最佳答案

您的代码是完全正确的。引起问题的是Spring框架中的错误。虽然,我没有在spring的问题跟踪器中找到它(或者可能没有进行记录),但是您可以通过更新依赖项来解决它。当然,您的代码将适用于spring-web> = 4.3.2.RELEASE的版本。

关于java - 超时阻止在ListenableFuture上,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42267408/

10-10 13:06