Browse Source

BI-29723 druid连接池生产线程阻塞

research/11.0
abel 6 years ago
parent
commit
35961254c6
  1. 46
      fine-druid/src/com/fr/third/alibaba/druid/pool/DruidDataSource.java

46
fine-druid/src/com/fr/third/alibaba/druid/pool/DruidDataSource.java

@ -139,6 +139,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
private DestroyTask destroyTask; private DestroyTask destroyTask;
private CreateConnectionThread createConnectionThread; private CreateConnectionThread createConnectionThread;
private PeriodDetectionThread periodDetectionThread;
private DestroyConnectionThread destroyConnectionThread; private DestroyConnectionThread destroyConnectionThread;
private LogStatsThread logStatsThread; private LogStatsThread logStatsThread;
private int createTaskCount; private int createTaskCount;
@ -613,10 +614,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} }
private void checkThread() throws SQLException { private void checkThread() throws SQLException {
if (createConnectionThread == null){ if (createConnectionThread == null) {
throw new IllegalStateException("createConnectionThread not start!"); throw new IllegalStateException("createConnectionThread not start!");
} }
if (destroyConnectionThread == null){ if (destroyConnectionThread == null) {
throw new IllegalStateException("destroyConnectionThread not start!"); throw new IllegalStateException("destroyConnectionThread not start!");
} }
if (!createConnectionThread.isStarted() && !destroyConnectionThread.isStarted()) { if (!createConnectionThread.isStarted() && !destroyConnectionThread.isStarted()) {
@ -780,7 +781,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
createAndLogThread(); createAndLogThread();
createAndStartCreatorThread(); createAndStartCreatorThread();
createAndStartDestroyThread(); createAndStartDestroyThread();
createAndStartDetectThread();
initedLatch.await(); initedLatch.await();
init = true; init = true;
@ -859,6 +860,14 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
initedLatch.countDown(); initedLatch.countDown();
} }
private void createAndStartDetectThread() {
if(createScheduler == null){
String threadName = "Druid-ConnectionPool-Detection-" + System.identityHashCode(this) + this.getUrl();
periodDetectionThread = new PeriodDetectionThread(threadName);
periodDetectionThread.start();
}
}
/** /**
* load filters from SPI ServiceLoader * load filters from SPI ServiceLoader
@ -1526,7 +1535,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
if (destroyConnectionThread != null) { if (destroyConnectionThread != null) {
destroyConnectionThread.interrupt(); destroyConnectionThread.interrupt();
} }
if (periodDetectionThread != null){
periodDetectionThread.interrupt();
}
if (destroySchedulerFuture != null) { if (destroySchedulerFuture != null) {
destroySchedulerFuture.cancel(true); destroySchedulerFuture.cancel(true);
} }
@ -2198,6 +2209,33 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
this.started = started; this.started = started;
} }
} }
//周期性检查生产线程状态,因为在终止生产线程的时候,为了不让生产线程疯狂重试数据库,只是生成了一个生产线程,但是并没有start,需要一个守护线程
//周期性检查线程状态,帮助其启动。
private class PeriodDetectionThread extends Thread {
public PeriodDetectionThread(String name) {
super(name);
this.setDaemon(true);
}
public void run() {
while(true) {
synchronized (DruidDataSource.this) {
//生产线程发生了切换,并且有线程在等待连接,需要主动唤醒生产线程,否则由
if (!createConnectionThread.started && !destroyConnectionThread.started && notEmptyWaitThreadCount > 0) {
createConnectionThread.setStarted(true);
createConnectionThread.start();
destroyConnectionThread.setStarted(true);
destroyConnectionThread.start();
}
}
try {
Thread.sleep(30000);
} catch (InterruptedException ignore) {
break;
}
}
}
}
public class DestroyConnectionThread extends Thread { public class DestroyConnectionThread extends Thread {
private volatile boolean started = true; private volatile boolean started = true;

Loading…
Cancel
Save