Browse Source

Merge pull request #103 in CORE/base-third from ~ABEL.CHEN/base-third:release/10.0 to release/10.0

* commit 'a9aed9e19281ca2ec9cbc96aa3f178c91850f375':
  注释
  BI-29723 druid连接池生产线程阻塞
  BI-29723 druid连接池生产连接线程阻塞
final/10.0.3
abel.chen 6 years ago
parent
commit
5ed670be98
  1. 51
      fine-druid/src/com/fr/third/alibaba/druid/pool/DruidDataSource.java

51
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;
@ -607,16 +608,21 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
createConnectionThread = new CreateConnectionThread(threadName); createConnectionThread = new CreateConnectionThread(threadName);
createConnectionThread.setStarted(false); createConnectionThread.setStarted(false);
String destroyName = "Druid-ConnectionPool-Destroy-" + System.identityHashCode(this) + this.getUrl(); String destroyName = "Druid-ConnectionPool-Destroy-" + System.identityHashCode(this) + this.getUrl();
if (destroyConnectionThread != null) {
if (!destroyConnectionThread.isInterrupted()) {
destroyConnectionThread.interrupt();
}
}
destroyConnectionThread = new DestroyConnectionThread(destroyName); destroyConnectionThread = new DestroyConnectionThread(destroyName);
destroyConnectionThread.setStarted(false); destroyConnectionThread.setStarted(false);
initedLatch = new CountDownLatch(2); initedLatch = new CountDownLatch(2);
} }
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 +786,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 +865,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 +1540,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 +2214,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) {
//生产线程发生了切换,并且有线程在等待连接,需要主动唤醒生产线程,否则由getConnection方法来唤醒生产线程
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