当我们的应用停止的时候,必须调用DruidDataSource.close()方法将数据源关闭。
close()方法主要完成了下面几件事情:
- 调用所有后台线程的中断方法,防止线程一直处于锁等待状态;
- 遍历连接池中的连接,调用连接的close()方法关闭连接;
- 销毁所有的过滤器。
下面我们就来详细看看close()方法。
//代码有删减
public void close() {
lock.lock();
try {
if (this.closed) {
return;
}
if (!this.inited) {
return;
}
this.closing = true;
//日志打印线程,该线程是后台线程,在数据源初始化的时候创建的,
//为了防止线程一直处于锁等待,调用线程中断
if (logStatsThread != null) {
logStatsThread.interrupt();
}
//连接创建后台线程
if (createConnectionThread != null) {
createConnectionThread.interrupt();
}
//连接销毁后台线程
if (destroyConnectionThread != null) {
destroyConnectionThread.interrupt();
}
//对应了createConnectionThread,如果使用了定时任务线程,那么可以通过createSchedulerFuture来终止定时任务线程
if (createSchedulerFuture != null) {
createSchedulerFuture.cancel(true);
}
//对应了destroyConnectionThread
if (destroySchedulerFuture != null) {
destroySchedulerFuture.cancel(true);
}
//遍历线程池中的每个线程
for (int i = 0; i < poolingCount; ++i) {
DruidConnectionHolder connHolder = connections[i];
for (PreparedStatementHolder stmtHolder : connHolder.getStatementPool().getMap().values()) {
connHolder.getStatementPool().closeRemovedStatement(stmtHolder);
}
connHolder.getStatementPool().getMap().clear();
Connection physicalConnection = connHolder.getConnection();
try {
physicalConnection.close();//关闭连接
} catch (Exception ex) {
LOG.warn("close connection error", ex);
}
connections[i] = null;
destroyCountUpdater.incrementAndGet(this);
}
poolingCount = 0;
unregisterMbean();//卸载
enable = false;
notEmpty.signalAll();
notEmptySignalCount++;
this.closed = true;
this.closeTimeMillis = System.currentTimeMillis();
disableException = new DataSourceDisableException();
//销毁所有的过滤器
for (Filter filter : filters) {
filter.destroy();
}
} finally {
this.closing = false;
lock.unlock();
}
}