最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

httpclient ConnectionHolder連接池連接保持源碼解析

 更新時(shí)間:2023年11月28日 09:38:26   作者:codecraft  
這篇文章主要為大家介紹了httpclient ConnectionHolder連接池連接保持源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

本文主要研究一下httpclient的ConnectionHolder

ConnectionReleaseTrigger

org/apache/http/conn/ConnectionReleaseTrigger.java

/**
 * Interface for releasing a connection. This can be implemented by various
 * "trigger" objects which are associated with a connection, for example
 * a {@link EofSensorInputStream} or the {@link ManagedHttpClientConnection} itself.
 * <p>
 * The methods in this interface can safely be called multiple times.
 * The first invocation releases the connection, subsequent calls
 * are ignored.
 *
 * @since 4.0
 */
public interface ConnectionReleaseTrigger {
    /**
     * Releases the connection with the option of keep-alive. This is a
     * "graceful" release and may cause IO operations for consuming the
     * remainder of a response entity. Use
     * {@link #abortConnection abortConnection} for a hard release. The
     * connection may be reused as specified by the duration.
     *
     * @throws IOException
     *             in case of an IO problem. The connection will be released
     *             anyway.
     */
    void releaseConnection()
        throws IOException;
    /**
     * Releases the connection without the option of keep-alive.
     * This is a "hard" release that implies a shutdown of the connection.
     * Use {@link #releaseConnection()} for a graceful release.
     *
     * @throws IOException      in case of an IO problem.
     *         The connection will be released anyway.
     */
    void abortConnection()
        throws IOException;
}
ConnectionReleaseTrigger定義了releaseConnection、abortConnection方法

ConnectionHolder

org/apache/http/impl/execchain/ConnectionHolder.java

@Contract(threading = ThreadingBehavior.SAFE)
class ConnectionHolder implements ConnectionReleaseTrigger, Cancellable, Closeable {
    private final Log log;
    private final HttpClientConnectionManager manager;
    private final HttpClientConnection managedConn;
    private final AtomicBoolean released;
    private volatile boolean reusable;
    private volatile Object state;
    private volatile long validDuration;
    private volatile TimeUnit timeUnit;
    public ConnectionHolder(
            final Log log,
            final HttpClientConnectionManager manager,
            final HttpClientConnection managedConn) {
        super();
        this.log = log;
        this.manager = manager;
        this.managedConn = managedConn;
        this.released = new AtomicBoolean(false);
    }
    public boolean isReusable() {
        return this.reusable;
    }
    public void markReusable() {
        this.reusable = true;
    }
    public void markNonReusable() {
        this.reusable = false;
    }
    public void setState(final Object state) {
        this.state = state;
    }
    public void setValidFor(final long duration, final TimeUnit timeUnit) {
        synchronized (this.managedConn) {
            this.validDuration = duration;
            this.timeUnit = timeUnit;
        }
    }
    private void releaseConnection(final boolean reusable) {
        if (this.released.compareAndSet(false, true)) {
            synchronized (this.managedConn) {
                if (reusable) {
                    this.manager.releaseConnection(this.managedConn,
                            this.state, this.validDuration, this.timeUnit);
                } else {
                    try {
                        this.managedConn.close();
                        log.debug("Connection discarded");
                    } catch (final IOException ex) {
                        if (this.log.isDebugEnabled()) {
                            this.log.debug(ex.getMessage(), ex);
                        }
                    } finally {
                        this.manager.releaseConnection(
                                this.managedConn, null, 0, TimeUnit.MILLISECONDS);
                    }
                }
            }
        }
    }
    @Override
    public void releaseConnection() {
        releaseConnection(this.reusable);
    }
    @Override
    public void abortConnection() {
        if (this.released.compareAndSet(false, true)) {
            synchronized (this.managedConn) {
                try {
                    this.managedConn.shutdown();
                    log.debug("Connection discarded");
                } catch (final IOException ex) {
                    if (this.log.isDebugEnabled()) {
                        this.log.debug(ex.getMessage(), ex);
                    }
                } finally {
                    this.manager.releaseConnection(
                            this.managedConn, null, 0, TimeUnit.MILLISECONDS);
                }
            }
        }
    }
    @Override
    public boolean cancel() {
        final boolean alreadyReleased = this.released.get();
        log.debug("Cancelling request execution");
        abortConnection();
        return !alreadyReleased;
    }
    public boolean isReleased() {
        return this.released.get();
    }
    @Override
    public void close() throws IOException {
        releaseConnection(false);
    }
}
ConnectionHolder實(shí)現(xiàn)了ConnectionReleaseTrigger接口,它提供了isReusable、markReusable、markNonReusable、setValidFor、releaseConnection、abortConnection、cancel、close等方法,其中releaseConnection是依賴reusable屬性來決定是關(guān)閉連接還是歸還連接,而abortConnection方法直接managedConn.shutdown(),然后在執(zhí)行manager.releaseConnection
releaseConnection在連接復(fù)用則執(zhí)行manager.releaseConnection,連接不復(fù)用先執(zhí)行managedConn.close()再執(zhí)行manager.releaseConnection(validDuratioin為0);
abortConnection先執(zhí)行this.managedConn.shutdown(),再執(zhí)行manager.releaseConnection(validDuratioin為0);
close與shutdown的區(qū)別在于close是優(yōu)雅關(guān)閉,會試圖flush內(nèi)部的output buffer,shutdown是強(qiáng)制關(guān)閉,不會試圖去flush內(nèi)部的buffer

MainClientExec

org/apache/http/impl/execchain/MainClientExec.java

public CloseableHttpResponse execute(
            final HttpRoute route,
            final HttpRequestWrapper request,
            final HttpClientContext context,
            final HttpExecutionAware execAware) throws IOException, HttpException {

                //......

                // The connection is in or can be brought to a re-usable state.
                if (reuseStrategy.keepAlive(response, context)) {
                    // Set the idle duration of this connection
                    final long duration = keepAliveStrategy.getKeepAliveDuration(response, context);
                    if (this.log.isDebugEnabled()) {
                        final String s;
                        if (duration &gt; 0) {
                            s = "for " + duration + " " + TimeUnit.MILLISECONDS;
                        } else {
                            s = "indefinitely";
                        }
                        this.log.debug("Connection can be kept alive " + s);
                    }
                    connHolder.setValidFor(duration, TimeUnit.MILLISECONDS);
                    connHolder.markReusable();
                } else {
                    connHolder.markNonReusable();
                }

                //......     

            // check for entity, release connection if possible
            final HttpEntity entity = response.getEntity();
            if (entity == null || !entity.isStreaming()) {
                // connection not needed and (assumed to be) in re-usable state
                connHolder.releaseConnection();
                return new HttpResponseProxy(response, null);
            }
            return new HttpResponseProxy(response, connHolder);

            //......                   
    }
MainClientExec的execute方法在通過requestExecutor.execute(request, managedConn, context)獲取到response的時(shí)候,會根據(jù)reuseStrategy.keepAlive(response, context)來判斷該conn是reusable還是nonReusable的,最后在成功場景,entity為null或者不是streaming的會執(zhí)行connHolder.releaseConnection(),異常場景執(zhí)行connHolder.abortConnection()

DefaultClientConnectionReuseStrategy

org/apache/http/impl/client/DefaultClientConnectionReuseStrategy.java

public class DefaultClientConnectionReuseStrategy extends DefaultConnectionReuseStrategy {

    public static final DefaultClientConnectionReuseStrategy INSTANCE = new DefaultClientConnectionReuseStrategy();

    @Override
    public boolean keepAlive(final HttpResponse response, final HttpContext context) {

        final HttpRequest request = (HttpRequest) context.getAttribute(HttpCoreContext.HTTP_REQUEST);
        if (request != null) {
            final Header[] connHeaders = request.getHeaders(HttpHeaders.CONNECTION);
            if (connHeaders.length != 0) {
                final TokenIterator ti = new BasicTokenIterator(new BasicHeaderIterator(connHeaders, null));
                while (ti.hasNext()) {
                    final String token = ti.nextToken();
                    if (HTTP.CONN_CLOSE.equalsIgnoreCase(token)) {
                        return false;
                    }
                }
            }
        }
        return super.keepAlive(response, context);
    }

}
DefaultClientConnectionReuseStrategy繼承了DefaultConnectionReuseStrategy,其keepAlive先判斷response的header有無Connection: close,沒有則返回false,有則調(diào)用super.keepAlive進(jìn)行進(jìn)一步判斷(`對于http1.0的返回false)

小結(jié)

httpclient的ConnectionHolder實(shí)現(xiàn)了ConnectionReleaseTrigger接口,它提供了isReusable、markReusable、markNonReusable、setValidFor、releaseConnection、abortConnection、cancel、close等方法;releaseConnection在連接復(fù)用則執(zhí)行manager.releaseConnection(validDuration為response的Keep-Alive返回的timeout參數(shù),若沒有則為-1),連接不復(fù)用先執(zhí)行managedConn.close()再執(zhí)行manager.releaseConnection(validDuration為0);abortConnection先執(zhí)行this.managedConn.shutdown(),再執(zhí)行manager.releaseConnection(validDuration為0);

MainClientExec的execute方法在通過requestExecutor.execute(request, managedConn, context)獲取到response的時(shí)候,會根據(jù)reuseStrategy.keepAlive(response, context)來判斷該conn是reusable還是nonReusable的,最后在成功場景,entity為null或者不是streaming的會執(zhí)行connHolder.releaseConnection(),異常場景執(zhí)行connHolder.abortConnection()

DefaultClientConnectionReuseStrategy繼承了DefaultConnectionReuseStrategy,其keepAlive先判斷response的header有無Connection: close,沒有則返回false,有則調(diào)用super.keepAlive進(jìn)行進(jìn)一步判斷(`對于http1.0的返回false)

close與shutdown的區(qū)別在于close是優(yōu)雅關(guān)閉,會試圖flush內(nèi)部的output buffer,shutdown是強(qiáng)制關(guān)閉,不會試圖去flush內(nèi)部的buffer

以上就是httpclient ConnectionHolder連接池連接保持源碼解析的詳細(xì)內(nèi)容,更多關(guān)于httpclient ConnectionHolder連接保持的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • maven打包名稱設(shè)置方式

    maven打包名稱設(shè)置方式

    這篇文章主要介紹了maven打包名稱設(shè)置方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • dubbo集成zipkin獲取Traceid的實(shí)現(xiàn)

    dubbo集成zipkin獲取Traceid的實(shí)現(xiàn)

    這篇文章主要介紹了dubbo集成zipkin獲取Traceid的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • springboot掃碼登錄的簡單實(shí)現(xiàn)

    springboot掃碼登錄的簡單實(shí)現(xiàn)

    本文主要介紹基于SpringBoot + Vue + Android實(shí)現(xiàn)的掃碼登錄,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • SpringBoot集成Nacos的詳細(xì)教程

    SpringBoot集成Nacos的詳細(xì)教程

    這篇文章主要介紹了SpringBoot集成Nacos的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • JDK 7U15在 Windows x86平臺下的安裝方法

    JDK 7U15在 Windows x86平臺下的安裝方法

    本文給大家分享的是如何在windows平臺下安裝JDK最新版的方法,十分的簡單全面,有需要的小伙伴可以參考下
    2016-05-05
  • java自動(dòng)生成ID號的方法

    java自動(dòng)生成ID號的方法

    這篇文章主要介紹了java自動(dòng)生成ID號的方法,涉及java生成ID號的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03
  • 如何基于spring security實(shí)現(xiàn)在線用戶統(tǒng)計(jì)

    如何基于spring security實(shí)現(xiàn)在線用戶統(tǒng)計(jì)

    這篇文章主要介紹了如何基于spring security實(shí)現(xiàn)在線用戶統(tǒng)計(jì),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 關(guān)于Maven混合配置私有倉庫和公共倉庫的問題

    關(guān)于Maven混合配置私有倉庫和公共倉庫的問題

    這篇文章主要介紹了Maven混合配置私有倉庫和公共倉庫,通過實(shí)例代碼詳細(xì)介紹了私有和公共倉庫混合配置的方法,需要的朋友可以參考下
    2022-06-06
  • Java消息隊(duì)列RabbitMQ之消息回調(diào)詳解

    Java消息隊(duì)列RabbitMQ之消息回調(diào)詳解

    這篇文章主要介紹了Java消息隊(duì)列RabbitMQ之消息回調(diào)詳解,消息回調(diào),其實(shí)就是消息確認(rèn)(生產(chǎn)者推送消息成功,消費(fèi)者接收消息成功)  , 對于程序來說,發(fā)送者沒法確認(rèn)是否發(fā)送成功,需要的朋友可以參考下
    2023-07-07
  • MyBatis-Plus使用sl4j日志打印SQL的代碼詳解

    MyBatis-Plus使用sl4j日志打印SQL的代碼詳解

    以下是關(guān)于使用 Spring Boot 起始器替換 slf4j-api 和 logback 依賴的詳細(xì)步驟和注意事項(xiàng),包括 MyBatis-Plus 的默認(rèn)日志級別信息,需要的朋友可以參考下
    2024-10-10

最新評論

乌什县| 扶绥县| 龙口市| 中宁县| 瑞安市| 吉木萨尔县| 濮阳县| 琼结县| 阿坝县| 宜城市| 平和县| 吉水县| 平泉县| 右玉县| 宁陵县| 桂林市| 陈巴尔虎旗| 清镇市| 沂源县| 灵石县| 乐山市| 宝兴县| 平凉市| 武安市| 乌拉特中旗| 河间市| 两当县| 宜州市| 永昌县| 宁武县| 大英县| 兴文县| 墨江| 彩票| 大兴区| 冷水江市| 萝北县| 若羌县| 伊宁市| 闸北区| 上思县|