翻了下之前记得笔记,发现有个对druid线程池的概要介绍,下面分析给大家
screenshot.png
(1)、 如果设置了maxWait或者构造函数参数传入的为true,则创建的ReentrantLock为公平锁,否者为非公平锁 (2)、 如果设置了initialSize>=1,则会启动是创建initialSize个数数据库物理连接到线程池。 (3)、 如果没设置createScheduler则创建并启动数据库连接创建线程,如果没设置destroyScheduler则创建并启动数据库连接回收线程,如果timeBetweenLogStatsMillis>0则创建logstat线程。
阿里巴巴长期招聘Java研发工程师p6,p7,p8等上不封顶级别,有意向的可以发简历给我,注明想去的部门和工作地点:1064454834@qq.com
screenshot.png
(1)、 如果当前数据库连接池有可用连接,则直接获取,否者如果设置createScheduler则开启一个新线程去创建物理连接,否者发送发送signal信号唤醒连接创建线程创建数据库物理连接,这种情况有分pollLast和takeLast,区别在于前者设置max wait超时时间,如果在时间内还没获取链接则返回null,后者则一直等待连接创建。
screenshot.png
(1)、 在调用conn.close时候会回收当前连接到线程池
screenshot.png
(1)、此图createScheduler=null的情况,为null从上面知道在初始化时候会新建 一个数据库连接创建线程。
实际上是个生产者消费者模式,生产者是连接创建线程和连接回收线程,消费者是获取连接的线程。 首先列下同步需要的条件变量和锁:
//独占锁(用来控制同是只有一个线程访问线程池),根据lockFair分为公平和非公平锁
lock = new ReentrantLock(lockFair);
//用来对消费和生成线程做同步
notEmpty = lock.newCondition();
empty = lock.newCondition();
//共享资源,线程池是一个数组
connections = new DruidConnectionHolder[maxActive];
消费者(获取数据库连接线程):
DruidConnectionHolder pollLast(){
DruidConnectionHolder holder;
try {
//加独占锁
lock.lockInterruptibly();
} catch (InterruptedException e) {
connectErrorCount.incrementAndGet();
throw new SQLException("interrupt", e);
}
try {
//通知连接创建线程,创建数据库连接
empty.signal();
//等待连接创建线程或者连接回收线程发送信号
estimate = notEmpty.awaitNanos(estimate);
//获取链接,并返回
decrementPoolingCount();
holder = connections[poolingCount];
connections[poolingCount] = null;
}finally{
//释放独占锁
lock.unlock();
}
holder.incrementUseCount();
DruidPooledConnection poolalbeConnection = new DruidPooledConnection(holder);
return poolalbeConnection;
}
生产者(连接创建线程):
public void run(){
try {
//独占锁
lock.lockInterruptibly();
} catch (InterruptedException e2) {
break;
}
try {
// 必须存在线程等待,才创建连接
if (poolingCount >= notEmptyWaitThreadCount) {
empty.await();//会释放当前独占锁
}
// 防止创建超过maxActive数量的连接
if (activeCount + poolingCount >= maxActive) {
empty.await();//会释放当前独占锁
}
} finally {
lock.unlock();
}
Connection connection = null;
try {
//创建物理链接
connection = createPhysicalConnection();
} catch (SQLException e) {
。。。。
} catch (RuntimeException e) {
。。。。
} catch (Error e) {
。。。。
}
lock.lock();
try {
//连接入池
connections[poolingCount] = holder;
incrementPoolingCount();
if (poolingCount > poolingPeak) {
poolingPeak = poolingCount;
poolingPeakTime = System.currentTimeMillis();
}
//发出信号,激活消费线程
notEmpty.signal();
notEmptySignalCount++;
} finally {
lock.unlock();
}
}
生产者(数据库连接回收线程):
protected void recycle(DruidPooledConnection pooledConnection){
lock.lockInterruptibly();
try {
activeCount--;
closeCount++;
connections[poolingCount] = e;
incrementPoolingCount();
if (poolingCount > poolingPeak) {
poolingPeak = poolingCount;
poolingPeakTime = lastActiveTimeMillis;
}
//激活消费线程
notEmpty.signal();
notEmptySignalCount++;
recycleCount++;
} finally {
lock.unlock();
}
}