我遇到过EntityUtils.consume(httpEntity);,但不确定它的实际作用。

例如:

try {

    //... some code

    HttpEntity httpEntity = httpResponse.getEntity();
    BufferedReader br = new BufferedReader(new InputStreamReader(http.Entity.getContent()));
    String line;
    while ((line = br.readLine())!= null) {
        System.out.println(line);
    }
    EntityUtils.consume(httpEntity);
} catch (Exception e) {
    //code
} finally {
    httpClient.getConnectionManager().shutdown();
}

为什么当EntityUtils.consume(httpEntity);块将关闭连接并且垃圾回收器将照顾finally时,作者为什么放入httpEntity

最佳答案

真正归结为成为“好公民”(并且真的知道HTTPClient接口(interface)的约定)。EntityUtils.consume要做的是释放httpEntity拥有的所有资源,这实际上意味着释放任何基础Stream并将Connection对象返回给它的池(如果您的连接管理器是多线程的)或释放连接管理器,以便它可以处理下一个请求。

如果您不使用entity,则发生的情况实际上取决于finally子句中“关闭连接管理器”的含义。它将关闭尚未发送回池的未决流/连接吗?我不确定它是否会按照契约(Contract)进行(尽管在实现方面,我认为确实如此)。如果不是,则可能是在泄漏系统资源(套接字等)。
发生的事情还可能取决于Entity对象的可能的终结方法,该方法可能(如果要执行的话)释放其资源,同样,不确定这样做是否在实体的契约(Contract)中。

让我们假设一分钟,ConnectionManager实际上在关闭时会正常关闭所有挂起的资源。您还需要使用实体吗?我说是,因为从现在开始的一个月后,有人将在同一try/finally块中修改您的代码并进行第二次HTTP调用,并且可能无法这样做,因为您没有按照应有的方式释放资源(例如,如果客户端位于单个连接池上,则不释放第一个连接将使第二个 call 失败。

因此,我的观点是:实体是资源,在不需要资源时应将其释放。指望别人在以后为您释放他们可能会伤害您将来。原始作者可能已经按照这些思路进行了思考。

作为附带说明,请注意,您编写的实现实际上将消耗读者直到基础流的末尾,因此,消耗调用实际上将什么都不做,但是在我看来,这是实现的详细信息(我的头顶是,一旦完全读取了响应流,连接对象就会自动释放/发送回http客户端的池中。
还请注意,如果您使用API​​提供的ResponseHandler机制,那么所有这些Consume逻辑也会从您身上抽象出来。
最后,API不保证response.getEntity永远不会返回null,因此您应该检查以避免NullPointerException

关于java - 作者为什么使用EntityUtils.consume(httpEntity);?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15969037/

10-10 22:43