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;
}