DruidDataSource类源码分析(五)

这是一个关于数据库连接池管理的线程实现,主要用于在需要时创建新的连接,并在连接不足时唤醒其他等待线程。线程大部分时间处于等待状态,不会占用大量CPU资源。当连接池中的连接达到特定条件时,线程会被激活创建连接,遵循最大连接数限制,并处理连接创建失败的情况。
摘要由CSDN通过智能技术生成

CreateConnectionThread( )

该流程独立运行,大部分时间处于等待状态,不会抢占cpu

但是当连接不够用时,就会被唤起追加连接,成功创建连接后将会唤醒其他正在等待获取可用连接的线程.

public class CreateConnectionThread extends Thread {

    public CreateConnectionThread(String name){
        super(name);
        this.setDaemon(true);
    }

    public void run() {
        initedLatch.countDown();

        long lastDiscardCount = 0;
        int errorCount = 0;
        for (;;) {
            // addLast
            try {
                lock.lockInterruptibly();
            } catch (InterruptedException e2) {
                break;
            }

            long discardCount = DruidDataSource.this.discardCount;
            boolean discardChanged = discardCount - lastDiscardCount > 0;
            lastDiscardCount = discardCount;

            try {
                boolean emptyWait = true;

                if (createError != null
                        && poolingCount == 0
                        && !discardChanged) {
                    emptyWait = false;
                }

                if (emptyWait
                        && asyncInit && createCount < initialSize) {
                    emptyWait = false;
                }

                if (emptyWait) {
                    // 判断时候存在线程等待
                    // 必须存在线程等待,才创建连接
                    if (poolingCount >= notEmptyWaitThreadCount //
                            && (!(keepAlive && activeCount + poolingCount < minIdle))
                            && !isFailContinuous()
                    ) {
                        empty.await();
                    }

                    // 防止创建超过maxActive数量的连接
                    if (activeCount + poolingCount >= maxActive) {
                        empty.await();
                        continue;
                    }
                }

            } catch (InterruptedException e) {
                lastCreateError = e;
                lastErrorTimeMillis = System.currentTimeMillis();

                if ((!closing) && (!closed)) {
                    LOG.error("create connection Thread Interrupted, url: " + jdbcUrl, e);
                }
                break;
            } finally {
                lock.unlock();
            }

            PhysicalConnectionInfo connection = null;

            try {
                connection = createPhysicalConnection();
            } catch (SQLException e) {
                LOG.error("create connection SQLException, url: " + jdbcUrl + ", errorCode " + e.getErrorCode()
                          + ", state " + e.getSQLState(), e);

                errorCount++;
                if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0) {
                    // fail over retry attempts
                    setFailContinuous(true);
                    if (failFast) {
                        lock.lock();
                        try {
                            notEmpty.signalAll();
                        } finally {
                            lock.unlock();
                        }
                    }

                    if (breakAfterAcquireFailure) {
                        break;
                    }

                    try {
                        Thread.sleep(timeBetweenConnectErrorMillis);
                    } catch (InterruptedException interruptEx) {
                        break;
                    }
                }
            } catch (RuntimeException e) {
                LOG.error("create connection RuntimeException", e);
                setFailContinuous(true);
                continue;
            } catch (Error e) {
                LOG.error("create connection Error", e);
                setFailContinuous(true);
                break;
            }

            if (connection == null) {
                continue;
            }

            boolean result = put(connection);
            if (!result) {
                JdbcUtils.close(connection.getPhysicalConnection());
                LOG.info("put physical connection to pool failed.");
            }

            errorCount = 0; // reset errorCount

            if (closing || closed) {
                break;
            }
        }
    }
}

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值