From c3e716557b27484bf6642737af9fb1672ddf1bcf Mon Sep 17 00:00:00 2001 From: wenshao Date: Wed, 7 Sep 2011 02:30:00 +0000 Subject: [PATCH] refactor git-svn-id: http://code.alibabatech.com/svn/druid/trunk@667 b9813039-fb51-4c41-a8b9-e21c2acb5095 --- .../alibaba/druid/pool/DruidDataSource.java | 86 +++++++++---------- .../java/com/alibaba/druid/pool/Global.java | 24 ++++++ 2 files changed, 63 insertions(+), 47 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/pool/Global.java diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index f37e0f5917..1e9838a7b9 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -48,7 +48,6 @@ import com.alibaba.druid.pool.vendor.OracleValidConnectionChecker; import com.alibaba.druid.pool.vendor.SybaseExceptionSorter; import com.alibaba.druid.proxy.DruidDriver; import com.alibaba.druid.proxy.jdbc.DataSourceProxyConfig; -import com.alibaba.druid.util.ConcurrentIdentityHashMap; import com.alibaba.druid.util.JdbcUtils; /** @@ -57,40 +56,35 @@ import com.alibaba.druid.util.JdbcUtils; */ public class DruidDataSource extends DruidAbstractDataSource implements DruidDataSourceMBean, ManagedDataSource, Referenceable { - private final static Log LOG = LogFactory.getLog(DruidDataSource.class); + private final static Log LOG = LogFactory.getLog(DruidDataSource.class); - // global instances - private static final Object PRESENT = new Object(); - private static final ConcurrentIdentityHashMap instances = new ConcurrentIdentityHashMap(); + private static final long serialVersionUID = 1L; - private static final long serialVersionUID = 1L; + private final ReentrantLock lock = new ReentrantLock(); - private final ReentrantLock lock = new ReentrantLock(); - - private final Condition notEmpty = lock.newCondition(); - private final Condition empty = lock.newCondition(); + private final Condition notEmpty = lock.newCondition(); + private final Condition empty = lock.newCondition(); // stats - private long connectCount = 0L; - private long closeCount = 0L; - private long connectErrorCount = 0L; - private long recycleCount = 0L; - private long createConnectionCount = 0L; - private long destroyCount = 0L; + private long connectCount = 0L; + private long closeCount = 0L; + private long connectErrorCount = 0L; + private long recycleCount = 0L; + private long createConnectionCount = 0L; + private long destroyCount = 0L; // store - private ConnectionHolder[] connections; - private int poolingCount = 0; - private int activeCount = 0; + private ConnectionHolder[] connections; + private int poolingCount = 0; + private int activeCount = 0; // threads - private CreateConnectionThread createConnectionThread; - private DestroyConnectionThread destoryConnectionThread; + private CreateConnectionThread createConnectionThread; + private DestroyConnectionThread destoryConnectionThread; - private final CountDownLatch initedLatch = new CountDownLatch( - 2); + private final CountDownLatch initedLatch = new CountDownLatch(2); - private boolean enable = false; + private boolean enable = false; public DruidDataSource(){ } @@ -121,7 +115,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } catch (InterruptedException e) { throw new SQLException("interrupt", e); } - + try { if (inited) { return; @@ -230,7 +224,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat inited = true; createdTime = new Date(); - instances.put(this, PRESENT); + Global.add(this); if (connectError != null && poolingCount == 0) { throw connectError; @@ -305,13 +299,13 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat private void discardConnection(Connection realConnection) throws SQLException { JdbcUtils.close(realConnection); - + try { lock.lockInterruptibly(); } catch (InterruptedException e) { throw new SQLException("interrupt", e); } - + try { activeCount--; } finally { @@ -327,7 +321,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } catch (InterruptedException e) { throw new SQLException("interrupt", e); } - + try { if (!enable) { connectErrorCount++; @@ -430,7 +424,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat boolean validate = testConnectionInternal(conn); if (!validate) { JdbcUtils.close(conn); - + lock.lockInterruptibly(); try { destroyCount++; @@ -462,7 +456,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } catch (InterruptedException interruptEx) { throw new SQLException("interrupt", interruptEx); } - + try { activeCount--; closeCount++; @@ -498,8 +492,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } } poolingCount = 0; - instances.remove(this); - + Global.remove(this); + enable = false; notEmpty.signalAll(); } finally { @@ -528,7 +522,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat while (poolingCount == 0) { empty.signal(); // send signal to CreateThread create connection notEmpty.await(); // signal by recycle or creator - + if (!enable) { connectErrorCount++; throw new DataSourceDisableException(); @@ -559,7 +553,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat try { estimate = notEmpty.awaitNanos(estimate); // signal by recycle or creator - + if (!enable) { connectErrorCount++; throw new DataSourceDisableException(); @@ -642,14 +636,14 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } catch (InterruptedException e2) { break; } - + try { // 必须存在线程等待,才创建连接 int waitThreadCount = lock.getWaitQueueLength(notEmpty); if (poolingCount >= waitThreadCount) { notEmpty.signal(); // 防止信号丢失引起的等待 - empty.await(); + empty.await(); continue; } @@ -659,8 +653,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat continue; } - - } catch (InterruptedException e) { break; } catch (RuntimeException e) { @@ -671,9 +663,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } finally { lock.unlock(); } - + Connection connection = null; - + try { connection = connectionFactory.createConnection(); } catch (SQLException e) { @@ -695,11 +687,11 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat LOG.error("create connection error", e); break; } - + if (connection == null) { continue; } - + lock.lock(); try { connections[poolingCount++] = new ConnectionHolder(DruidDataSource.this, connection); @@ -800,7 +792,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } public static Set getInstances() { - return instances.keySet(); + return Global.getInstances(); } public int getRawDriverMajorVersion() { @@ -843,7 +835,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } catch (InterruptedException e) { return; } - + try { final int checkCount = poolingCount - minIdle; for (int i = 0; i < checkCount; ++i) { @@ -877,7 +869,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat destroyCount++; } } - + public int getWaitThreadCount() { lock.lock(); try { @@ -886,7 +878,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat lock.unlock(); } } - + public int getLockQueueLength() { return lock.getQueueLength(); } diff --git a/src/main/java/com/alibaba/druid/pool/Global.java b/src/main/java/com/alibaba/druid/pool/Global.java new file mode 100644 index 0000000000..6eb0dd8b99 --- /dev/null +++ b/src/main/java/com/alibaba/druid/pool/Global.java @@ -0,0 +1,24 @@ +package com.alibaba.druid.pool; + +import java.util.Set; + +import com.alibaba.druid.util.ConcurrentIdentityHashMap; + +public class Global { + + // global instances + private static final Object PRESENT = new Object(); + private static final ConcurrentIdentityHashMap instances = new ConcurrentIdentityHashMap(); + + public static void add(DruidDataSource dataSource) { + instances.put(dataSource, PRESENT); + } + + public static void remove(DruidDataSource dataSource) { + instances.remove(dataSource); + } + + public static Set getInstances() { + return instances.keySet(); + } +}