|
|
|
@ -139,6 +139,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
|
|
|
|
private DestroyTask destroyTask; |
|
|
|
|
|
|
|
|
|
private CreateConnectionThread createConnectionThread; |
|
|
|
|
private PeriodDetectionThread periodDetectionThread; |
|
|
|
|
private DestroyConnectionThread destroyConnectionThread; |
|
|
|
|
private LogStatsThread logStatsThread; |
|
|
|
|
private int createTaskCount; |
|
|
|
@ -780,7 +781,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
|
|
|
|
createAndLogThread(); |
|
|
|
|
createAndStartCreatorThread(); |
|
|
|
|
createAndStartDestroyThread(); |
|
|
|
|
|
|
|
|
|
createAndStartDetectThread(); |
|
|
|
|
initedLatch.await(); |
|
|
|
|
init = true; |
|
|
|
|
|
|
|
|
@ -859,6 +860,14 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
|
|
|
|
|
|
|
|
|
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 |
|
|
|
@ -1526,7 +1535,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
|
|
|
|
if (destroyConnectionThread != null) { |
|
|
|
|
destroyConnectionThread.interrupt(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (periodDetectionThread != null){ |
|
|
|
|
periodDetectionThread.interrupt(); |
|
|
|
|
} |
|
|
|
|
if (destroySchedulerFuture != null) { |
|
|
|
|
destroySchedulerFuture.cancel(true); |
|
|
|
|
} |
|
|
|
@ -2198,6 +2209,33 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
|
|
|
|
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 { |
|
|
|
|
private volatile boolean started = true; |
|
|
|
|