How can I catch InterruptedException when making h

2019-07-22 20:48发布

I have a Callable that makes a http request via Apache library. However, if the request takes too long, I would like to kill the thread. To do this, I can interrupt the Callable, but I need to catch the InterruptedException in order to stop myself. How can I do this?

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;
}

Note future.cancel(true) doesn't kill the thread because all it does is interrupt the thread, and my code doesn't catch the InterruptedException. However, I cannot figure out how to do this since httpClient.execute is blocking, and I cannot divide the work into chunks.

Would it be sufficient to just catch InterruptedException while calling httpClient.execute()?

    public CloseableHttpResponse call() throws Exception {
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(getCustomSslConnectionSocketFactory())
                .build();
        try {
            return httpClient.execute(new HttpGet(url));
        } catch (InterruptedException) {
            return null;
        }
    }

1条回答
ゆ 、 Hurt°
2楼-- · 2019-07-22 21:43

To do this, I can interrupt the Callable, but I need to catch the InterruptedException in order to stop myself. How can I do this?

You can't. None of the external methods of the HttpClient throw InterruptedException. You cannot catch an exception that is not thrown by the methods. Interrupting a thread causes only those methods that throw InterruptedException to throw it. This includes Thread.sleep(), Object.wait(), and others. The rest of the methods must test for Thread.currentThread().isInterrupted() to see the interrupt flag.

I recommend setting http client parameters that set the socket timeouts. I'm not sure which version of Apache HttpClient you are using but we are using 4.2.2 and do something like the following:

BasicHttpParams clientParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(clientParams, socketTimeoutMillis);
HttpConnectionParams.setSoTimeout(clientParams, socketTimeoutMillis);
HttpClient client = new DefaultHttpClient(clientParams);
查看更多
登录 后发表回答