有时不可能中断线程,尤其是当线程在Socket上执行阻塞操作时。
因此,与其在超时时取消任务,不如在http连接上设置超时。
不幸的是,每个连接工厂和RestTemplate都设置了时间限制,因此每个请求必须使用它自己的RestTemplate。
您可以为每个任务创建新的RestTemplate,或者使用ThreadLocal或资源池重用以前创建的模板。
例如,使用Thread local的任务可能如下所示:
public class Task implements Callable<DataResponse> { private DataKey key; private ThreadLocal<RestTemplate> restTemplateThreadLocal = ThreadLocal.withInitial(()->new RestTemplate(new SimpleClientHttpRequestFactory())); public Task(DataKey key) { this.key = key; } private SimpleClientHttpRequestFactory getConnectionFactory(){ return (SimpleClientHttpRequestFactory)restTemplateThreadLocal.get().getRequestFactory(); } @Override public DataResponse call() { DataResponse dataResponse = null; String response = null; try { String url = createURL(); //it is up to you, how to set connection and read timeouts from provided key.getTimeout getConnectionFactory().setConnectTimeout(1000); getConnectionFactory().setReadTimeout(key.getTimeout()); response = restTemplateThreadLocal.get().getForObject(url, String.class); // it is a successful response dataResponse = new DataResponse(response, DataErrorEnum.NONE, DataStatusEnum.SUCCESS); } catch (RestClientException ex) { PotoLogging.logErrors(ex, DataErrorEnum.SERVER_DOWN, key); dataResponse = new DataResponse(null, DataErrorEnum.SERVER_DOWN, DataStatusEnum.ERROR); } catch (Exception ex) { PotoLogging.logErrors(ex, DataErrorEnum.CLIENT_ERROR, key); dataResponse = new DataResponse(null, DataErrorEnum.CLIENT_ERROR, DataStatusEnum.ERROR); } return dataResponse; } // create a URL by using key object private String createURL() { String url = somepre; return url; } }顺便说一句。Spring还提供了AsyncRestTemplate,可以使您的代码更简单。如果与Netty4ClientHttpRequestFactory一起使用,则可以获取基于NIO的客户端连接。在这种情况下,即使建立Http连接,您也应该能够中断您的任务。
以下是简短示例。它使用NIO,因此您不必担心超时后是否真的取消了请求。
URI url = new URI("http://www.chicagotribune.com/news/ct-college-of-dupage-investigation-met-20150330-story.html"); Netty4ClientHttpRequestFactory asyncRequestFactory = new Netty4ClientHttpRequestFactory(); AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(asyncRequestFactory); ListenableFuture<ResponseEntity<String>> entity = asyncRestTemplate.getForEntity(url, String.class); System.out.println("entity.get() = " + entity.get()); asyncRequestFactory.destroy();


