在使用Apache发出http请求时如何捕获InterruptedException?

时间:2013-12-19 22:58:13

标签: java multithreading apache threadpool interrupt

我有一个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;
        }
    }

1 个答案:

答案 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);