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

httpclient getPoolEntryBlocking連接池方法源碼解讀

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

本文主要研究一下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獲取空閑連接,然后進行過期判斷,再判斷是否close,如果已經(jīng)close則從available中移除,獲取成功的話則從available移除,添加到leased然后返回。如果獲取不到則先判斷連接是否超出maxPerRoute,超出則先移除最近使用的,之后在沒有超出maxPerRoute的條件下通過connFactory.create創(chuàng)建然后返回,超出則放入到pending中進行等待

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獲取空閑連接,然后進行過期判斷,再判斷是否close,如果已經(jīng)close則從available中移除,獲取成功的話則從available移除,添加到leased然后返回。如果獲取不到則先判斷連接是否超出maxPerRoute,超出則先移除最近使用的,之后在沒有超出maxPerRoute的條件下通過connFactory.create創(chuàng)建然后返回,超出則放入到pending中進行等待。

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

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

相關(guān)文章

  • SpringBoot--- SpringSecurity進行注銷權(quán)限控制的配置方法

    SpringBoot--- SpringSecurity進行注銷權(quán)限控制的配置方法

    這篇文章主要介紹了SpringBoot--- SpringSecurity進行注銷,權(quán)限控制,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • RestTemplat中關(guān)于getForobject方法的使用

    RestTemplat中關(guān)于getForobject方法的使用

    這篇文章主要介紹了RestTemplat中關(guān)于getForobject方法的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Spring Boot加密配置文件方法介紹

    Spring Boot加密配置文件方法介紹

    這篇文章主要介紹了SpringBoot加密配置文件,近期在對開發(fā)框架安全策略方面進行升級優(yōu)化,提供一些通用場景的解決方案,本文針對配置文件加密進行簡單的分享
    2023-01-01
  • Java獲取IP地址以及MAC地址的示例代碼

    Java獲取IP地址以及MAC地址的示例代碼

    IP地址是用于在網(wǎng)絡(luò)上識別設(shè)備的唯一地址,而MAC地址是設(shè)備的物理地址,本文主要介紹了Java獲取IP地址以及MAC地址的示例代碼,具有一定的參考價值,感興趣的可以了解一下
    2024-04-04
  • 別在Java代碼里亂打日志了,這才是正確的打日志姿勢

    別在Java代碼里亂打日志了,這才是正確的打日志姿勢

    這篇文章主要介紹了別在Java代碼里亂打日志了,這才是正確的打日志姿勢,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • MyBatis中使用分頁插件PageHelper實現(xiàn)分頁功能

    MyBatis中使用分頁插件PageHelper實現(xiàn)分頁功能

    分頁是經(jīng)常使用的功能,本文主要介紹了Mybatis中處理特殊SQL處理邏輯,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 阿里四面之Spring Exception的原理解析

    阿里四面之Spring Exception的原理解析

    本文給大家介紹阿里四面之Spring Exception的原理解析,本文通過錯誤場景分析給大家詳細介紹Spring異常處理流程,感興趣的朋友一起看看吧
    2021-10-10
  • SpringBoot多RabbitMQ連接集成的實現(xiàn)示例

    SpringBoot多RabbitMQ連接集成的實現(xiàn)示例

    本文介紹了如何在SpringBoot應(yīng)用中優(yōu)雅地處理多個RabbitMQ連接的問題,避免配置沖突,通過自定義ConnectionFactory、RabbitTemplate和ListenerContainerFactoryBean,并使用@Qualifier注解進行Bean隔離,感興趣的可以了解一下
    2026-02-02
  • Java使用ExecutorService來停止線程服務(wù)

    Java使用ExecutorService來停止線程服務(wù)

    這篇文章主要介紹了Java使用ExecutorService來停止線程服務(wù),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Java前后端的JSON傳輸方式(前后端JSON格式轉(zhuǎn)換)

    Java前后端的JSON傳輸方式(前后端JSON格式轉(zhuǎn)換)

    這篇文章主要介紹了Java前后端的JSON傳輸方式(前后端JSON格式轉(zhuǎn)換),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04

最新評論

永善县| 富裕县| 栾川县| 嵩明县| 汤原县| 武平县| 峨边| 禄丰县| 定远县| 平原县| 观塘区| 剑阁县| 呼图壁县| 东乌| 萨迦县| 上犹县| 南漳县| 博爱县| 峨眉山市| 阿巴嘎旗| 邳州市| 古田县| 乐至县| 双峰县| 兰州市| 吉林省| 纳雍县| 酉阳| 盐源县| 离岛区| 怀集县| 大港区| 荔浦县| 肇州县| 曲麻莱县| 临汾市| 安徽省| 海兴县| 抚顺县| 昭觉县| 开鲁县|