欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

httpclient getPoolEntryBlocking連接池方法源碼解讀

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

本文主要研究一下httpclient的getPoolEntryBlocking

getPoolEntryBlocking

org/apache/http/pool/AbstractConnPool.java

private E getPoolEntryBlocking(
            final T route, final Object state,
            final long timeout, final TimeUnit timeUnit,
            final Future<E> future) throws IOException, InterruptedException, ExecutionException, TimeoutException {
        Date deadline = null;
        if (timeout > 0) {
            deadline = new Date (System.currentTimeMillis() + timeUnit.toMillis(timeout));
        }
        this.lock.lock();
        try {
            final RouteSpecificPool<T, C, E> pool = getPool(route);
            E entry;
            for (;;) {
                Asserts.check(!this.isShutDown, "Connection pool shut down");
                if (future.isCancelled()) {
                    throw new ExecutionException(operationAborted());
                }
                for (;;) {
                    entry = pool.getFree(state);
                    if (entry == null) {
                        break;
                    }
                    if (entry.isExpired(System.currentTimeMillis())) {
                        entry.close();
                    }
                    if (entry.isClosed()) {
                        this.available.remove(entry);
                        pool.free(entry, false);
                    } else {
                        break;
                    }
                }
                if (entry != null) {
                    this.available.remove(entry);
                    this.leased.add(entry);
                    onReuse(entry);
                    return entry;
                }
                // New connection is needed
                final int maxPerRoute = getMax(route);
                // Shrink the pool prior to allocating a new connection
                final int excess = Math.max(0, pool.getAllocatedCount() + 1 - maxPerRoute);
                if (excess > 0) {
                    for (int i = 0; i < excess; i++) {
                        final E lastUsed = pool.getLastUsed();
                        if (lastUsed == null) {
                            break;
                        }
                        lastUsed.close();
                        this.available.remove(lastUsed);
                        pool.remove(lastUsed);
                    }
                }
                if (pool.getAllocatedCount() < maxPerRoute) {
                    final int totalUsed = this.leased.size();
                    final int freeCapacity = Math.max(this.maxTotal - totalUsed, 0);
                    if (freeCapacity > 0) {
                        final int totalAvailable = this.available.size();
                        if (totalAvailable > freeCapacity - 1) {
                            if (!this.available.isEmpty()) {
                                final E lastUsed = this.available.removeLast();
                                lastUsed.close();
                                final RouteSpecificPool<T, C, E> otherpool = getPool(lastUsed.getRoute());
                                otherpool.remove(lastUsed);
                            }
                        }
                        final C conn = this.connFactory.create(route);
                        entry = pool.add(conn);
                        this.leased.add(entry);
                        return entry;
                    }
                }
                boolean success = false;
                try {
                    pool.queue(future);
                    this.pending.add(future);
                    if (deadline != null) {
                        success = this.condition.awaitUntil(deadline);
                    } else {
                        this.condition.await();
                        success = true;
                    }
                    if (future.isCancelled()) {
                        throw new ExecutionException(operationAborted());
                    }
                } finally {
                    // In case of 'success', we were woken up by the
                    // connection pool and should now have a connection
                    // waiting for us, or else we're shutting down.
                    // Just continue in the loop, both cases are checked.
                    pool.unqueue(future);
                    this.pending.remove(future);
                }
                // check for spurious wakeup vs. timeout
                if (!success && (deadline != null && deadline.getTime() <= System.currentTimeMillis())) {
                    break;
                }
            }
            throw new TimeoutException("Timeout waiting for connection");
        } finally {
            this.lock.unlock();
        }
    }
AbstractConnPool提供了getPoolEntryBlocking,lease內(nèi)部就是通過這個方法來獲取連接的。它主要是通過pool.getFree獲取空閑連接,然后進(jìn)行過期判斷,再判斷是否close,如果已經(jīng)close則從available中移除,獲取成功的話則從available移除,添加到leased然后返回。如果獲取不到則先判斷連接是否超出maxPerRoute,超出則先移除最近使用的,之后在沒有超出maxPerRoute的條件下通過connFactory.create創(chuàng)建然后返回,超出則放入到pending中進(jìn)行等待

InternalConnectionFactory

org/apache/http/impl/conn/PoolingHttpClientConnectionManager.java

static class InternalConnectionFactory implements ConnFactory<HttpRoute, ManagedHttpClientConnection> {
        private final ConfigData configData;
        private final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory;
        InternalConnectionFactory(
                final ConfigData configData,
                final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory) {
            super();
            this.configData = configData != null ? configData : new ConfigData();
            this.connFactory = connFactory != null ? connFactory :
                ManagedHttpClientConnectionFactory.INSTANCE;
        }
        @Override
        public ManagedHttpClientConnection create(final HttpRoute route) throws IOException {
            ConnectionConfig config = null;
            if (route.getProxyHost() != null) {
                config = this.configData.getConnectionConfig(route.getProxyHost());
            }
            if (config == null) {
                config = this.configData.getConnectionConfig(route.getTargetHost());
            }
            if (config == null) {
                config = this.configData.getDefaultConnectionConfig();
            }
            if (config == null) {
                config = ConnectionConfig.DEFAULT;
            }
            return this.connFactory.create(route, config);
        }
    }
InternalConnectionFactory實現(xiàn)了ConnFactory接口,其create方法委托給ManagedHttpClientConnectionFactory.INSTANCE

ManagedHttpClientConnectionFactory

public class ManagedHttpClientConnectionFactory
        implements HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> {
    private static final AtomicLong COUNTER = new AtomicLong();
    public static final ManagedHttpClientConnectionFactory INSTANCE = new ManagedHttpClientConnectionFactory();
    private final Log log = LogFactory.getLog(DefaultManagedHttpClientConnection.class);
    private final Log headerLog = LogFactory.getLog("org.apache.http.headers");
    private final Log wireLog = LogFactory.getLog("org.apache.http.wire");
    private final HttpMessageWriterFactory<HttpRequest> requestWriterFactory;
    private final HttpMessageParserFactory<HttpResponse> responseParserFactory;
    private final ContentLengthStrategy incomingContentStrategy;
    private final ContentLengthStrategy outgoingContentStrategy;
    //......
    public ManagedHttpClientConnection create(final HttpRoute route, final ConnectionConfig config) {
        final ConnectionConfig cconfig = config != null ? config : ConnectionConfig.DEFAULT;
        CharsetDecoder charDecoder = null;
        CharsetEncoder charEncoder = null;
        final Charset charset = cconfig.getCharset();
        final CodingErrorAction malformedInputAction = cconfig.getMalformedInputAction() != null ?
                cconfig.getMalformedInputAction() : CodingErrorAction.REPORT;
        final CodingErrorAction unmappableInputAction = cconfig.getUnmappableInputAction() != null ?
                cconfig.getUnmappableInputAction() : CodingErrorAction.REPORT;
        if (charset != null) {
            charDecoder = charset.newDecoder();
            charDecoder.onMalformedInput(malformedInputAction);
            charDecoder.onUnmappableCharacter(unmappableInputAction);
            charEncoder = charset.newEncoder();
            charEncoder.onMalformedInput(malformedInputAction);
            charEncoder.onUnmappableCharacter(unmappableInputAction);
        }
        final String id = "http-outgoing-" + Long.toString(COUNTER.getAndIncrement());
        return new LoggingManagedHttpClientConnection(
                id,
                log,
                headerLog,
                wireLog,
                cconfig.getBufferSize(),
                cconfig.getFragmentSizeHint(),
                charDecoder,
                charEncoder,
                cconfig.getMessageConstraints(),
                incomingContentStrategy,
                outgoingContentStrategy,
                requestWriterFactory,
                responseParserFactory);
    }    
}
ManagedHttpClientConnectionFactory的create方法創(chuàng)建的是LoggingManagedHttpClientConnection,它繼承了DefaultManagedHttpClientConnection增加了logging的特性,而DefaultManagedHttpClientConnection繼承了DefaultBHttpClientConnection,聲明實現(xiàn)了ManagedHttpClientConnection

小結(jié)

AbstractConnPool提供了getPoolEntryBlocking,lease內(nèi)部就是通過這個方法來獲取連接的。它主要是通過pool.getFree獲取空閑連接,然后進(jìn)行過期判斷,再判斷是否close,如果已經(jīng)close則從available中移除,獲取成功的話則從available移除,添加到leased然后返回。如果獲取不到則先判斷連接是否超出maxPerRoute,超出則先移除最近使用的,之后在沒有超出maxPerRoute的條件下通過connFactory.create創(chuàng)建然后返回,超出則放入到pending中進(jìn)行等待。

MainClientExec優(yōu)先通過connManager.requestConnection是經(jīng)過連接池管理的,如果連接不夠用,通過connFactory.create創(chuàng)建新的ManagedHttpClientConnection,最后MainClientExec會再判斷一下managedConn是否open,沒有的話會通過establishRoute來建立連接(HttpClientConnectionManager.connect會創(chuàng)建socket然后進(jìn)行connect然后bind到managedConn)

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

相關(guān)文章

  • 使用Feign傳遞請求頭信息(Finchley版本)

    使用Feign傳遞請求頭信息(Finchley版本)

    這篇文章主要介紹了使用Feign傳遞請求頭信息(Finchley版本),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java爬蟲Jsoup主要類及功能使用詳解

    java爬蟲Jsoup主要類及功能使用詳解

    這篇文章主要為大家介紹了java爬蟲Jsoup主要類及功能使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • SpringBoot中MockMVC單元測試的實現(xiàn)

    SpringBoot中MockMVC單元測試的實現(xiàn)

    Mock是一種用于模擬和替換類的對象的方法,以便在單元測試中獨立于外部資源進(jìn)行測試,本文主要介紹了SpringBoot中MockMVC單元測試的實現(xiàn),具有應(yīng)該的參考價值,感興趣的可以了解一下
    2024-02-02
  • Java中的攔截器、過濾器、監(jiān)聽器用法詳解

    Java中的攔截器、過濾器、監(jiān)聽器用法詳解

    這篇文章主要介紹了Java中的攔截器、過濾器、監(jiān)聽器用法,詳細(xì)分析了Java攔截器、過濾器、監(jiān)聽器的功能、使用方法及相關(guān)注意事項,需要的朋友可以參考下
    2017-05-05
  • Spring Boot 中的 @ConditionalOnBean 注解作用及基本用法

    Spring Boot 中的 @ConditionalOnBean 注解作用及基

    在 Spring Boot 中,@ConditionalOnBean 可以幫助我們根據(jù) 是否存在特定 Bean 來 動態(tài)注冊 Bean,廣泛用于 按需加載、自動配置 等場景,本文給大家介紹Spring Boot 中的 @ConditionalOnBean 注解,感興趣的朋友一起看看吧
    2025-04-04
  • SpringBoot接口返回結(jié)果封裝方法實例詳解

    SpringBoot接口返回結(jié)果封裝方法實例詳解

    在實際項目中,一般會把結(jié)果放在一個封裝類中,封裝類中包含http狀態(tài)值,狀態(tài)消息,以及實際的數(shù)據(jù)。這里主要記錄兩種方式,通過實例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-09-09
  • java中Servlet Cookie取不到值原因解決辦法

    java中Servlet Cookie取不到值原因解決辦法

    這篇文章主要介紹了java中Servlet Cookie取不到值原因解決辦法的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Java equals()方法使用詳解及總結(jié)

    Java equals()方法使用詳解及總結(jié)

    這篇文章主要介紹了Java equals()方法使用詳解及總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Spring 多線程事務(wù)控制的實踐

    Spring 多線程事務(wù)控制的實踐

    本文主要介紹了Spring 多線程事務(wù)控制的實踐,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-09-09
  • Spring Boot 2.x中Actuator的一些知識點

    Spring Boot 2.x中Actuator的一些知識點

    這篇文章主要給大家介紹了關(guān)于Spring Boot 2.x中Actuator的一些知識點,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Spring Boot 2.x具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09

最新評論