我有一个Callable通过Apache库发出http请求。但是,如果请求时间太长,我想杀死该线程。为此,我可以中断Callable,但我需要捕获InterruptedException以阻止自己。我怎么能这样做?
private final class HelloWorker implements Callable<String> {
private String url;
public HelloWorker(String url) {
this.url = url;
}
public CloseableHttpResponse call() throws Exception {
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(getCustomSslConnectionSocketFactory())
.build();
return httpClient.execute(new HttpGet(url));
}
}
private CloseableResponse getHttpResponse(String url) {
ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
Future<String> future = executorService.submit(new HelloWorker());
try {
// try to get a response within 5 seconds
return future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
// kill the thread
future.cancel(true);
}
return null;
}
注意future.cancel(true)
不会终止线程,因为它所做的只是中断线程,而我的代码没有捕获InterruptedException。但是,由于httpClient.execute
阻塞,我无法弄清楚如何执行此操作,我无法将工作划分为块。
在调用httpClient.execute()
时只捕获InterruptedException是否足够?
public CloseableHttpResponse call() throws Exception {
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(getCustomSslConnectionSocketFactory())
.build();
try {
return httpClient.execute(new HttpGet(url));
} catch (InterruptedException) {
return null;
}
}
答案 0 :(得分:2)
为此,我可以中断Callable,但我需要捕获InterruptedException以阻止自己。我怎么能这样做?
你做不到。 HttpClient
抛出InterruptedException
的所有外部方法都没有。您无法捕获方法未抛出的异常。中断线程会导致仅那些抛出InterruptedException
的方法抛出它。其中包括Thread.sleep()
,Object.wait()
等。其余方法必须测试Thread.currentThread().isInterrupted()
以查看中断标志。
我建议设置用于设置套接字超时的http客户端参数。我不确定您使用的是哪个版本的Apache HttpClient
,但我们使用的是4.2.2并执行以下操作:
BasicHttpParams clientParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(clientParams, socketTimeoutMillis);
HttpConnectionParams.setSoTimeout(clientParams, socketTimeoutMillis);
HttpClient client = new DefaultHttpClient(clientParams);