【问题标题】:How can I catch InterruptedException when making http request with Apache?使用 Apache 发出 http 请求时如何捕获 InterruptedException?
【发布时间】:2014-01-08 17:00:16
【问题描述】:

我有一个通过 Apache 库发出 http 请求的 Callable。但是,如果请求花费的时间太长,我想杀死线程。为此,我可以中断 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;
        }
    }

【问题讨论】:

  • a Future 将捕获您未捕获的每个 Throwable.get()如果你需要它会给你。
  • "但是,如果请求时间过长,我想杀死线程"。不,你没有。你想设置一个超时。
  • 如果对您有帮助,记得接受。

标签: java multithreading apache threadpool interrupt


【解决方案1】:

为此,我可以中断 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    • 1970-01-01
    相关资源
    最近更新 更多