diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 172f928e70..3deb74b1fd 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -53,6 +53,7 @@ import javax.sql.ConnectionPoolDataSource; import javax.sql.PooledConnection; import com.alibaba.druid.Constants; +import com.alibaba.druid.DruidRuntimeException; import com.alibaba.druid.TransactionTimeoutException; import com.alibaba.druid.VERSION; import com.alibaba.druid.filter.AutoLoad; @@ -684,6 +685,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat period = 1000; } destroySchedulerFuture = destroyScheduler.scheduleAtFixedRate(destoryTask, period, period, TimeUnit.MILLISECONDS); + initedLatch.countDown(); return; } @@ -693,9 +695,14 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } protected void createAndStartCreatorThread() { - String threadName = "Druid-ConnectionPool-Create-" + System.identityHashCode(this); - createConnectionThread = new CreateConnectionThread(threadName); - createConnectionThread.start(); + if (createScheduler == null) { + String threadName = "Druid-ConnectionPool-Create-" + System.identityHashCode(this); + createConnectionThread = new CreateConnectionThread(threadName); + createConnectionThread.start(); + return; + } + + initedLatch.countDown(); } /** @@ -2635,6 +2642,15 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat lock.unlock(); } } + + + public ScheduledExecutorService getCreateScheduler() { + return createScheduler; + } + + public void setCreateScheduler(ScheduledExecutorService createScheduler) { + this.createScheduler = createScheduler; + } public ScheduledExecutorService getDestroyScheduler() { return destroyScheduler; @@ -2642,6 +2658,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat public void setDestroyScheduler(ScheduledExecutorService destroyScheduler) { + if (isInited()) { + throw new DruidRuntimeException("dataSource inited."); + } this.destroyScheduler = destroyScheduler; } diff --git a/src/test/java/com/alibaba/druid/bvt/pool/CreateSchedulerTest.java b/src/test/java/com/alibaba/druid/bvt/pool/CreateSchedulerTest.java new file mode 100644 index 0000000000..987cadcff2 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/CreateSchedulerTest.java @@ -0,0 +1,46 @@ +package com.alibaba.druid.bvt.pool; + +import java.sql.Connection; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.pool.DruidDataSource; + +public class CreateSchedulerTest extends TestCase { + + private DruidDataSource dataSource; + private ScheduledExecutorService createScheduler; + + protected void setUp() throws Exception { + createScheduler = Executors.newScheduledThreadPool(1); + + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setDestroyScheduler(createScheduler); + dataSource.setMinEvictableIdleTimeMillis(10); + dataSource.setTimeBetweenEvictionRunsMillis(10); + } + + protected void tearDown() throws Exception { + dataSource.close(); + createScheduler.shutdown(); + } + + public void test_connectAndClose() throws Exception { + Connection[] connections = new Connection[8]; + for (int i = 0; i < connections.length; ++i) { + connections[i] = dataSource.getConnection(); + } + + for (int i = 0; i < connections.length; ++i) { + connections[i].close(); + } + + Thread.sleep(100); + Assert.assertEquals(0, dataSource.getPoolingCount()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DestorySchedulerTest.java b/src/test/java/com/alibaba/druid/bvt/pool/DestorySchedulerTest.java new file mode 100644 index 0000000000..695e1a3e98 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/DestorySchedulerTest.java @@ -0,0 +1,46 @@ +package com.alibaba.druid.bvt.pool; + +import java.sql.Connection; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.pool.DruidDataSource; + +public class DestorySchedulerTest extends TestCase { + + private DruidDataSource dataSource; + private ScheduledExecutorService destroyScheduler; + + protected void setUp() throws Exception { + destroyScheduler = Executors.newScheduledThreadPool(1); + + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setDestroyScheduler(destroyScheduler); + dataSource.setMinEvictableIdleTimeMillis(10); + dataSource.setTimeBetweenEvictionRunsMillis(10); + } + + protected void tearDown() throws Exception { + dataSource.close(); + destroyScheduler.shutdown(); + } + + public void test_connectAndClose() throws Exception { + Connection[] connections = new Connection[8]; + for (int i = 0; i < connections.length; ++i) { + connections[i] = dataSource.getConnection(); + } + + for (int i = 0; i < connections.length; ++i) { + connections[i].close(); + } + + Thread.sleep(100); + Assert.assertEquals(0, dataSource.getPoolingCount()); + } +}