设为首页 加入收藏

TOP

数据库的连接学习之为什么C3P0连接池那么慢?(二)
2018-04-17 09:08:05 】 浏览:459
Tags:数据库 连接 习之 为什么 C3P0 那么
this.setDriverClassLoaded( true ); } catch (Exception e) { SqlUtils.toSQLException("Cannot instantiate specified JDBC driver. Exception while initializing named, forced-to-use driver class'" + driverClass +"'", e); } } else driver = DriverManager.getDriver( jdbcUrl ); } return driver; }

具体的连接池管理是BasicResourcePool,可以看下代码,里面全都是synchronized方法。并发性能怎么能好。

再来看下Druid的实现,DruidDataSource

 private DruidPooledConnection getConnectionInternal(long maxWait) throws SQLException {
        DruidConnectionHolder holder;

        for (boolean createDirect = false;;) {
                // 带有超时的连接获取
                if (maxWait > 0) {
                    holder = pollLast(nanos);
                } else {
                    holder = takeLast();
                }
    }

并发环境下去拿连接时,并没有在读操作上加锁,比互斥锁的性能要高

互斥锁是一种比较保守的策略,像synchronized,它避免了写写冲突,写读冲突,和读读冲突,对于数据库连接池,应用程序来拿,是一个读操作比较多的,允许多个读同时操作,能够提高系统的并发性。

private DruidConnectionHolder pollLast(long nanos) throws InterruptedException, SQLException {
        long estimate = nanos;

        for (;;) {
            if (poolingCount == 0) {
             // 通知创建线程去创建连接
             emptySignal(); 
             }

            decrementPoolingCount();
            // 从数组中获取连接
            DruidConnectionHolder last = connections[poolingCount];
            connections[poolingCount] = null;

            long waitNanos = nanos - estimate;
            last.setLastNotEmptyWaitNanos(waitNanos);

            return last;
        }
    }

在创建连接线程,销毁连接线程中增加写锁

 private boolean put(DruidConnectionHolder holder) {
        // 加锁
        lock.lock();
        try {
            if (poolingCount >= maxActive) {
                return false;
            }
            connections[poolingCount] = holder;
            incrementPoolingCount();

            if (poolingCount > poolingPeak) {
                poolingPeak = poolingCount;
                poolingPeakTime = System.currentTimeMillis();
            }
            //发出连接池非空信号,等待的线程开始处理
            notEmpty.signal();
            notEmptySignalCount++;

            if (createScheduler != null) {
                createTaskCount--;

                if (poolingCount + createTaskCount < notEmptyWaitThreadCount //
                    && activeCount + poolingCount + createTaskCount < maxActive) {
                    emptySignal();
                }
            }
        } finally {
            lock.unlock();
        }
        return true;
    }
首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇一个sql语句错误引出的关于group .. 下一篇oracle基础教程之包的创建、调用..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目