`
Donald_Draper
  • 浏览: 980252 次
社区版块
存档分类
最新评论

C3P0属性设置和数据库连接池的获取

    博客分类:
  • C3P0
阅读更多
C3P0 ComboPooledDataSource初始化:http://donald-draper.iteye.com/blog/2343522
C3P0 DriverManagerDataSource初始化:http://donald-draper.iteye.com/blog/2343564
WrapperConnectionPoolDataSource初始化:http://donald-draper.iteye.com/blog/2345008
C3P0属性设置和数据库连接池的获取:http://donald-draper.iteye.com/blog/2345084
在C3p0构建时,有驱动相关信息及数据库连接池相关的属性设置,及连接的获取,今天我们先来看一下,驱动相关信息及数据库连接池相关的属性设置,在连接的获取。
从下面几句开始,
cpDSource = new ComboPooledDataSource();
//设置DriverManagerDataSource驱动相关信息
cpDSource.setDriverClass(props.getProperty("driver"));
cpDSource.setJdbcUrl(props.getProperty("url"));
cpDSource.setUser(props.getProperty("user"));
cpDSource.setPassword(props.getProperty("password"));

//AbstractComboPooledDataSource的两个关键内部成员DriverManagerDataSource,WrapperConnectionPoolDataSource
public AbstractComboPooledDataSource(boolean autoregister)
    {
        //
        super(autoregister);
	//新建驱动数据源管理器
        dmds = new DriverManagerDataSource();
	//新建数据库连接池
        wcpds = new WrapperConnectionPoolDataSource();
	//设置数据连接池的数据源驱动管理器
        wcpds.setNestedDataSource(dmds);
        try
        {
            setConnectionPoolDataSource(wcpds);
        }
        catch(PropertyVetoException e)
        {
            logger.log(MLevel.WARNING, "Hunh??? This can't happen. We haven't set up any listeners to veto the property change yet!", e);
            throw new RuntimeException((new StringBuilder()).append("Hunh??? This can't happen. We haven't set up any listeners to veto the property change yet! ").append(e).toString());
        }
        setUpPropertyEvents();
    }
}
//设置driverClass
public void setDriverClass(String driverClass)
        throws PropertyVetoException
    {
        dmds.setDriverClass(driverClass);
    }
 //设置jdbcUrl
 public void setJdbcUrl(String jdbcUrl)
    {
        if(diff(dmds.getJdbcUrl(), jdbcUrl))
        {
            dmds.setJdbcUrl(jdbcUrl);
            resetPoolManager(false);
        }
    }
   //设置user
    public void setUser(String user)
    {
        if(diff(dmds.getUser(), user))
        {
            dmds.setUser(user);
            resetPoolManager(false);
        }
    }
    //设置password
    public void setPassword(String password)
    {
        if(diff(dmds.getPassword(), password))
        {
            dmds.setPassword(password);
            resetPoolManager(false);
        }
    }

//设置WrapperConnectionPoolDataSource相关属性
cpDSource.setInitialPoolSize(5);
cpDSource.setMaxPoolSize(30);
cpDSource.setMinPoolSize(5);
cpDSource.setMaxStatements(100);
cpDSource.setIdleConnectionTestPeriod(60);
cpDSource.setBreakAfterAcquireFailure(false);
cpDSource.setAcquireRetryAttempts(30);
cpDSource.setTestConnectionOnCheckout(false);

//设置连接失败尝试连接数
public void setAcquireRetryAttempts(int acquireRetryAttempts)
    {
        if(diff(wcpds.getAcquireRetryAttempts(), acquireRetryAttempts))
        {
            wcpds.setAcquireRetryAttempts(acquireRetryAttempts);
            resetPoolManager(false);
        }
    }
 
    public int getAcquireRetryDelay()
    {
        return wcpds.getAcquireRetryDelay();
    }

    public void setAcquireRetryDelay(int acquireRetryDelay)
    {
        if(diff(wcpds.getAcquireRetryDelay(), acquireRetryDelay))
        {
            wcpds.setAcquireRetryDelay(acquireRetryDelay);
            resetPoolManager(false);
        }
    }

    public boolean isAutoCommitOnClose()
    {
        return wcpds.isAutoCommitOnClose();
    }
    //设置是否自动提交
    public void setAutoCommitOnClose(boolean autoCommitOnClose)
    {
        if(diff(wcpds.isAutoCommitOnClose(), autoCommitOnClose))
        {
            wcpds.setAutoCommitOnClose(autoCommitOnClose);
            resetPoolManager(false);
        }
    }
    
    public int getInitialPoolSize()
    {
        return wcpds.getInitialPoolSize();
    }
    //连接池初始化大小
    public void setInitialPoolSize(int initialPoolSize)
    {
        if(diff(wcpds.getInitialPoolSize(), initialPoolSize))
        {
            wcpds.setInitialPoolSize(initialPoolSize);
            resetPoolManager(false);
        }
    }

    public int getMaxIdleTime()
    {
        return wcpds.getMaxIdleTime();
    }
   //maxIdleTime
    public void setMaxIdleTime(int maxIdleTime)
    {
        if(diff(wcpds.getMaxIdleTime(), maxIdleTime))
        {
            wcpds.setMaxIdleTime(maxIdleTime);
            resetPoolManager(false);
        }
    }
    //maxPoolSize
    public void setMaxPoolSize(int maxPoolSize)
    {
        if(diff(wcpds.getMaxPoolSize(), maxPoolSize))
        {
            wcpds.setMaxPoolSize(maxPoolSize);
            resetPoolManager(false);
        }
    }
   //maxStatements
    public void setMaxStatements(int maxStatements)
    {
        if(diff(wcpds.getMaxStatements(), maxStatements))
        {
            wcpds.setMaxStatements(maxStatements);
            resetPoolManager(false);
        }
    }

从上面可以看出cpDSource初始化driver相关属性,是初始化数据源驱动管理器DriverManagerDataSource的属性;初始化poolConnection相关属性,是初始化数据库连接池包装类WrapperConnectionPoolDataSource的属性。

再看连接的获取,从下面一句开始,
con = cpDSource.getConnection();

此方法在ComboPooledDataSource和其父类中都没,追溯到AbstractComboPooledDataSource的
父类AbstractPoolBackedDataSource
//AbstractPoolBackedDataSource
public abstract class AbstractPoolBackedDataSource extends PoolBackedDataSourceBase
    implements PooledDataSource
{
    public Connection getConnection()
        throws SQLException
    {
         //获取数据库连接池管理器
        PooledConnection pc = getPoolManager().getPool().checkoutPooledConnection();
	//从数据库连接池,返回数据库连接
        return pc.getConnection();
    }
}

先看获取数据库连接池管理器
//获取数据库连接池管理器
PooledConnection pc = getPoolManager().getPool().checkoutPooledConnection();
   
    //获取数据库连接池管理器
  
 private synchronized C3P0PooledConnectionPoolManager getPoolManager()
        throws SQLException
    {
        if(poolManager == null)
        {
	   //获取数据源数据库连接池
            ConnectionPoolDataSource cpds = assertCpds();
	    //构建数据库连接池管理器
            poolManager = new C3P0PooledConnectionPoolManager(cpds, null, null, getNumHelperThreads(), getIdentityToken(), getDataSourceName());
            if(logger.isLoggable(MLevel.INFO))
                logger.info((new StringBuilder()).append("Initializing c3p0 pool... ").append(toString(true)).toString());
        }
        return poolManager;
    }
    //确定数据源数据库连接池
     private synchronized ConnectionPoolDataSource assertCpds()
        throws SQLException
    {
        if(is_closed)
            throw new SQLException((new StringBuilder()).append(this).append(" has been closed() -- you can no longer use it.").toString());
       //获取数据源数据库连接池
	ConnectionPoolDataSource out = getConnectionPoolDataSource();
        if(out == null)
            throw new SQLException("Attempted to use an uninitialized PoolBackedDataSource. Please call setConnectionPoolDataSource( ... ) to initialize.");
        else
            return out;
    }

//PoolBackedDataSourceBase
public class PoolBackedDataSourceBase extends IdentityTokenResolvable
    implements Referenceable, Serializable
{
   //获取数据源数据库连接池
public synchronized ConnectionPoolDataSource getConnectionPoolDataSource()
    {
        return connectionPoolDataSource;
    }
   
    public synchronized void setConnectionPoolDataSource(ConnectionPoolDataSource connectionPoolDataSource)
        throws PropertyVetoException
    {
        ConnectionPoolDataSource oldVal = this.connectionPoolDataSource;
        if(!eqOrBothNull(oldVal, connectionPoolDataSource))
            vcs.fireVetoableChange("connectionPoolDataSource", oldVal, connectionPoolDataSource);
        this.connectionPoolDataSource = connectionPoolDataSource;
        if(!eqOrBothNull(oldVal, connectionPoolDataSource))
            pcs.firePropertyChange("connectionPoolDataSource", oldVal, connectionPoolDataSource);
    }
}

这个数据源数据连接池是什么呢?还记得我们前面,有讲过AbstractComboPooledDataSource的构造有这么一段
public AbstractComboPooledDataSource(boolean autoregister)
    {
        super(autoregister);
        dmds = new DriverManagerDataSource();
        wcpds = new WrapperConnectionPoolDataSource();
        wcpds.setNestedDataSource(dmds);
        try
        {
	    //设置数据源数据库连接池为WrapperConnectionPoolDataSource
            setConnectionPoolDataSource(wcpds);
        }
    }

现在回到getPoolManager的构建数据库连接池管理器这一句
poolManager = new C3P0PooledConnectionPoolManager(cpds, null, null, getNumHelperThreads(), getIdentityToken(), getDataSourceName());

//C3P0PooledConnectionPoolManager
public final class C3P0PooledConnectionPoolManager
{
    private static final boolean POOL_EVENT_SUPPORT = false;
    private static final CoalesceChecker COALESCE_CHECKER;
    static final Coalescer COALESCER;
    static final int DFLT_NUM_TASK_THREADS_PER_DATA_SOURCE = 3;
    ThreadPoolAsynchronousRunner taskRunner;//
    ThreadPoolAsynchronousRunner deferredStatementDestroyer;
    Timer timer;
    ResourcePoolFactory rpfact;
    Map authsToPools;
    final ConnectionPoolDataSource cpds;
    final Map propNamesToReadMethods;
    final Map flatPropertyOverrides;
    final Map userOverrides;
    final DbAuth defaultAuth;
    final String parentDataSourceIdentityToken;
    final String parentDataSourceName;
    int num_task_threads;
    static 
    {
        COALESCE_CHECKER = IdentityTokenizedCoalesceChecker.INSTANCE;
        COALESCER = CoalescerFactory.createCoalescer(COALESCE_CHECKER, true, false);
    }
    //初始化C3P0PooledConnectionPoolManager,cpds为WrapperConnectionPoolDataSource
    public C3P0PooledConnectionPoolManager(ConnectionPoolDataSource cpds, Map flatPropertyOverrides, Map forceUserOverrides, int num_task_threads, String parentDataSourceIdentityToken, String parentDataSourceName)
        throws SQLException
    {
        //任务线程数
        this.num_task_threads = 3;
        try
        {
            this.cpds = cpds;//初始化数据库连接池
            this.flatPropertyOverrides = flatPropertyOverrides;
            this.num_task_threads = num_task_threads;
            this.parentDataSourceIdentityToken = parentDataSourceIdentityToken;
            this.parentDataSourceName = parentDataSourceName;
            DbAuth auth = null;
            if(flatPropertyOverrides != null)
            {
                String overrideUser = (String)flatPropertyOverrides.get("overrideDefaultUser");
                String overridePassword = (String)flatPropertyOverrides.get("overrideDefaultPassword");
                if(overrideUser == null)
                {
                    overrideUser = (String)flatPropertyOverrides.get("user");
                    overridePassword = (String)flatPropertyOverrides.get("password");
                }
                if(overrideUser != null)
                    auth = new DbAuth(overrideUser, overridePassword);
            }
            if(auth == null)
	        //初始化数据库验证
                auth = C3P0ImplUtils.findAuth(cpds);
            defaultAuth = auth;
            Map tmp = new HashMap();
            BeanInfo bi = Introspector.getBeanInfo(cpds.getClass());
            PropertyDescriptor pds[] = bi.getPropertyDescriptors();
            PropertyDescriptor pd = null;
            int i = 0;
            for(int len = pds.length; i < len; i++)
            {
                pd = pds[i];
                String name = pd.getName();
                Method m = pd.getReadMethod();
                if(m != null)
                    tmp.put(name, m);
            }

            propNamesToReadMethods = tmp;
            if(forceUserOverrides == null)
            {
                Method uom = (Method)propNamesToReadMethods.get("userOverridesAsString");
                if(uom != null)
                {
                    String uoas = (String)uom.invoke(cpds, (Object[])null);
                    Map uo = C3P0ImplUtils.parseUserOverridesAsString(uoas);
                    userOverrides = uo;
                } else
                {
                    userOverrides = Collections.EMPTY_MAP;
                }
            } else
            {
                userOverrides = forceUserOverrides;
            }

            poolsInit();
        }
        catch(Exception e)
        {
            logger.log(MLevel.FINE, null, e);
            throw SqlUtils.toSQLException(e);
        }
    }
}
//连接池初始化
private void poolsInit()
    {
        boolean privilege_spawned_threads = getPrivilegeSpawnedThreads();
        String contextClassLoaderSource = getContextClassLoaderSource();
        class _cls1ContextClassLoaderPoolsInitThread extends Thread
        {

            public void run()
            {
	        //
                maybePrivilegedPoolsInit(privilege_spawned_threads);
            }

            final boolean val$privilege_spawned_threads;
            final C3P0PooledConnectionPoolManager this$0;

            _cls1ContextClassLoaderPoolsInitThread(boolean flag)
            {
                this.this$0 = C3P0PooledConnectionPoolManager.this;
                privilege_spawned_threads = flag;
                super();
                setContextClassLoader(ccl);
            }
        }

        try
        {
            if("library".equalsIgnoreCase(contextClassLoaderSource))
            {
	        //
                Thread t = new _cls1ContextClassLoaderPoolsInitThread(privilege_spawned_threads);
                t.start();
                t.join();
            } else
            if("none".equalsIgnoreCase(contextClassLoaderSource))
            {
                Thread t = new _cls1ContextClassLoaderPoolsInitThread(privilege_spawned_threads);
                t.start();
                t.join();
            } else
            {
                if(logger.isLoggable(MLevel.WARNING) && !"caller".equalsIgnoreCase(contextClassLoaderSource))
                    logger.log(MLevel.WARNING, (new StringBuilder()).append("Unknown contextClassLoaderSource: ").append(contextClassLoaderSource).append(" -- should be 'caller', 'library', or 'none'. Using default value 'caller'.").toString());
                maybePrivilegedPoolsInit(privilege_spawned_threads);
            }
        }
    }

 private void maybePrivilegedPoolsInit(boolean privilege_spawned_threads)
    {
        if(privilege_spawned_threads)
        {
            PrivilegedAction privilegedPoolsInit = new PrivilegedAction() {

                public Void run()
                {
		    //委托给_poolsInit
                    _poolsInit();
                    return null;
                }

                public volatile Object run()
                {
                    return run();
                }

                final C3P0PooledConnectionPoolManager this$0;

            
            {
                this.this$0 = C3P0PooledConnectionPoolManager.this;
                super();
            }
            };
            AccessController.doPrivileged(privilegedPoolsInit);
        } else
        {
            _poolsInit();
        }
    }
    //终于找个了poolsInit的关键,初始化定时任务调度器,及死锁检测线程,及延时死锁检测线程
    private synchronized void _poolsInit()
    {
        String idStr = idString();
        timer = new Timer((new StringBuilder()).append(idStr).append("-AdminTaskTimer").toString(), true);
        int matt = getMaxAdministrativeTaskTime();
	//创建任务线程调度器
        taskRunner = createTaskRunner(num_task_threads, matt, timer, (new StringBuilder()).append(idStr).append("-HelperThread").toString());
        int num_deferred_close_threads = getStatementCacheNumDeferredCloseThreads();
        if(num_deferred_close_threads > 0)
            deferredStatementDestroyer = createTaskRunner(num_deferred_close_threads, matt, timer, (new StringBuilder()).append(idStr).append("-DeferredStatementDestroyerThread").toString());
        else
            deferredStatementDestroyer = null;
        rpfact = BasicResourcePoolFactory.createNoEventSupportInstance(taskRunner, timer);
        authsToPools = new HashMap();
    }

从上面可以看出getPoolManager()实际上,是初始化数据库连接池管理器C3P0PooledConnectionPoolManager,初始化C3P0PooledConnectionPoolManager的ConnectionPoolDataSource(WrapperConnectionPoolDataSource)及定时任务调度器,及死锁检测线程,及延时死锁检测线程。

回到,获取数据库连接池这一句的第二点getPool()
PooledConnection pc = getPoolManager().getPool().checkoutPooledConnection();

从上面可以看到getPoolManager()返回的是C3P0PooledConnectionPoolManager,
public C3P0PooledConnectionPool getPool()
        throws SQLException
    {
        return getPool(defaultAuth);
    }
public synchronized C3P0PooledConnectionPool getPool(DbAuth auth)
        throws SQLException
    {
        //Map authsToPools;Map<DbAuth,C3P0PooledConnectionPool>
        C3P0PooledConnectionPool out = (C3P0PooledConnectionPool)authsToPools.get(auth);
        if(out == null)
        {
	    //创建数据库连接池
            out = createPooledConnectionPool(auth);
            authsToPools.put(auth, out);
            if(logger.isLoggable(MLevel.FINE))
                logger.log(MLevel.FINE, (new StringBuilder()).append("Created new pool for auth, username (masked): '").append(auth.getMaskedUserString()).append("'.").toString());
        }
        return out;
    }
//创建数据库连接池
 private C3P0PooledConnectionPool createPooledConnectionPool(DbAuth auth)
        throws SQLException
    {
        String userName = auth.getUser();
        String automaticTestTable = getAutomaticTestTable(userName);
        String realTestQuery;
        if(automaticTestTable != null)
        {
            realTestQuery = initializeAutomaticTestTable(automaticTestTable, auth);
            if(getPreferredTestQuery(userName) != null && logger.isLoggable(MLevel.WARNING))
                logger.logp(MLevel.WARNING, com/mchange/v2/c3p0/impl/C3P0PooledConnectionPoolManager.getName(), "createPooledConnectionPool", "[c3p0] Both automaticTestTable and preferredTestQuery have been set! Using automaticTestTable, and ignoring preferredTestQuery. Real test query is ''{0}''.", realTestQuery);
        } else
        {
            if(!defaultAuth.equals(auth))
                ensureFirstConnectionAcquisition(auth);
            realTestQuery = getPreferredTestQuery(userName);
        }
	//创建数据库连接池
        C3P0PooledConnectionPool out = new C3P0PooledConnectionPool(cpds, auth, getMinPoolSize(userName), getMaxPoolSize(userName), getInitialPoolSize(userName), getAcquireIncrement(userName), getAcquireRetryAttempts(userName), getAcquireRetryDelay(userName), getBreakAfterAcquireFailure(userName), getCheckoutTimeout(userName), getIdleConnectionTestPeriod(userName), getMaxIdleTime(userName), getMaxIdleTimeExcessConnections(userName), getMaxConnectionAge(userName), getPropertyCycle(userName), getUnreturnedConnectionTimeout(userName), getDebugUnreturnedConnectionStackTraces(userName), getForceSynchronousCheckins(userName), getTestConnectionOnCheckout(userName), getTestConnectionOnCheckin(userName), getMaxStatements(userName), getMaxStatementsPerConnection(userName), getConnectionTester(userName), getConnectionCustomizer(userName), realTestQuery, rpfact, taskRunner, deferredStatementDestroyer, parentDataSourceIdentityToken);
        return out;
    }

//C3P0PooledConnectionPool
public final class C3P0PooledConnectionPool
{
    final ResourcePool rp;
    final ConnectionEventListener cl = new ConnectionEventListenerImpl();
    final ConnectionTester connectionTester;
    final GooGooStatementCache scache;
    final boolean c3p0PooledConnections;
    final boolean effectiveStatementCache;
    final int checkoutTimeout;
    final AsynchronousRunner sharedTaskRunner;
    final AsynchronousRunner deferredStatementDestroyer;
    final ThrowableHolderPool thp = new ThrowableHolderPool();
    final InUseLockFetcher inUseLockFetcher;
    private static InUseLockFetcher RESOURCE_ITSELF_IN_USE_LOCK_FETCHER = new ResourceItselfInUseLockFetcher();
    private static InUseLockFetcher C3P0_POOLED_CONNECION_NESTED_LOCK_LOCK_FETCHER = new C3P0PooledConnectionNestedLockLockFetcher();
 
    C3P0PooledConnectionPool(final ConnectionPoolDataSource cpds, final DbAuth auth, int min, int max, int start, int inc, int acq_retry_attempts, 
            int acq_retry_delay, boolean break_after_acq_failure, int checkoutTimeout, int idleConnectionTestPeriod, int maxIdleTime, int maxIdleTimeExcessConnections, int maxConnectionAge, 
            int propertyCycle, int unreturnedConnectionTimeout, boolean debugUnreturnedConnectionStackTraces, boolean forceSynchronousCheckins, final boolean testConnectionOnCheckout, final boolean testConnectionOnCheckin, int maxStatements, 
            int maxStatementsPerConnection, final ConnectionTester connectionTester, final ConnectionCustomizer connectionCustomizer, final String testQuery, ResourcePoolFactory fact, ThreadPoolAsynchronousRunner taskRunner, ThreadPoolAsynchronousRunner deferredStatementDestroyer, 
            final String parentDataSourceIdentityToken)
        throws SQLException
    {
        try
        {
            if(maxStatements > 0 && maxStatementsPerConnection > 0)
                scache = new DoubleMaxStatementCache(taskRunner, deferredStatementDestroyer, maxStatements, maxStatementsPerConnection);
            else
            if(maxStatementsPerConnection > 0)
                scache = new PerConnectionMaxOnlyStatementCache(taskRunner, deferredStatementDestroyer, maxStatementsPerConnection);
            else
            if(maxStatements > 0)
                scache = new GlobalMaxOnlyStatementCache(taskRunner, deferredStatementDestroyer, maxStatements);
            else
                scache = null;
            this.connectionTester = connectionTester;
            this.checkoutTimeout = checkoutTimeout;
            sharedTaskRunner = taskRunner;
            this.deferredStatementDestroyer = deferredStatementDestroyer;
            c3p0PooledConnections = cpds instanceof WrapperConnectionPoolDataSource;
            effectiveStatementCache = c3p0PooledConnections && scache != null;
	     class _cls1PooledConnectionResourcePoolManager
                implements com.mchange.v2.resourcepool.ResourcePool.Manager
            {}
	    com.mchange.v2.resourcepool.ResourcePool.Manager manager = new _cls1PooledConnectionResourcePoolManager();
            synchronized(fact)
            {
                fact.setMin(min);
                fact.setMax(max);
                fact.setStart(start);
                fact.setIncrement(inc);
                fact.setIdleResourceTestPeriod(idleConnectionTestPeriod * 1000);
                fact.setResourceMaxIdleTime(maxIdleTime * 1000);
                fact.setExcessResourceMaxIdleTime(maxIdleTimeExcessConnections * 1000);
                fact.setResourceMaxAge(maxConnectionAge * 1000);
                fact.setExpirationEnforcementDelay(propertyCycle * 1000);
                fact.setDestroyOverdueResourceTime(unreturnedConnectionTimeout * 1000);
                fact.setDebugStoreCheckoutStackTrace(debugUnreturnedConnectionStackTraces);
                fact.setForceSynchronousCheckins(forceSynchronousCheckins);
                fact.setAcquisitionRetryAttempts(acq_retry_attempts);
                fact.setAcquisitionRetryDelay(acq_retry_delay);
                fact.setBreakOnAcquisitionFailure(break_after_acq_failure);
		//BasicResourcePoolFactory创建资源池BasicResourcePool
                rp = fact.createPool(manager);
            }
     }
}

//BasicResourcePoolFactory
public class BasicResourcePoolFactory extends ResourcePoolFactory
{
    int start;
    int min;
    int max;
    int inc;
    int retry_attempts;
    int retry_delay;
    long idle_resource_test_period;
    long max_age;
    long max_idle_time;
    long excess_max_idle_time;
    long destroy_overdue_resc_time;
    long expiration_enforcement_delay;
    boolean break_on_acquisition_failure;
    boolean debug_store_checkout_stacktrace;
    boolean force_synchronous_checkins;
    AsynchronousRunner taskRunner;
    boolean taskRunner_is_external;
    RunnableQueue asyncEventQueue;
    boolean asyncEventQueue_is_external;
    Timer timer;
    boolean timer_is_external;
    int default_num_task_threads;
    Set liveChildren;
    //创建资源池BasicResourcePool
 public synchronized ResourcePool createPool(ResourcePool.Manager mgr)
        throws ResourcePoolException
    {
        if(liveChildren == null)
            createThreadResources();
        ResourcePool child = new BasicResourcePool(mgr, start, min, max, inc, retry_attempts, retry_delay, idle_resource_test_period, max_age, max_idle_time, excess_max_idle_time, destroy_overdue_resc_time, expiration_enforcement_delay, break_on_acquisition_failure, debug_store_checkout_stacktrace, force_synchronous_checkins, taskRunner, asyncEventQueue, timer, this);
        liveChildren.add(child);
        return child;
    }
}

来看BasicResourcePool的构造
class BasicResourcePool
    implements ResourcePool
{
    final ResourcePool.Manager mgr;
    final int start;
    final int min;
    final int max;
    final int inc;
    final int num_acq_attempts;
    final int acq_attempt_delay;
    final long check_idle_resources_delay;
    final long max_resource_age;
    final long max_idle_time;
    final long excess_max_idle_time;
    final long destroy_unreturned_resc_time;
    final long expiration_enforcement_delay;
    final boolean break_on_acquisition_failure;
    final boolean debug_store_checkout_exceptions;
    final boolean force_synchronous_checkins;
    final long pool_start_time = System.currentTimeMillis();
    final BasicResourcePoolFactory factory;//资源池工厂
    final AsynchronousRunner taskRunner;
    final RunnableQueue asyncEventQueue;//异步事件定时任务调度器
    final ResourcePoolEventSupport rpes;
    Timer cullAndIdleRefurbishTimer;
    TimerTask cullTask;
    TimerTask idleRefurbishTask;
    HashSet acquireWaiters;//获取连接池等待线程
    HashSet otherWaiters;
    int pending_acquires;
    int pending_removes;
    int target_pool_size;
    HashMap managed;
    //数据库连接资源池,初始化时从WrapperConnectionPoolDataSource获取连接,添加到unused
    //中LinkedList<Connection>
    LinkedList unused;
    HashSet excluded;
    Map formerResources;
    Set idleCheckResources;
    boolean force_kill_acquires;
    boolean broken;
    long failed_checkins;
    long failed_checkouts;
    long failed_idle_tests;
    Throwable lastCheckinFailure;
    Throwable lastCheckoutFailure;
    Throwable lastIdleTestFailure;
    Throwable lastResourceTestFailure;
    Throwable lastAcquisitionFailiure;
    Object exampleResource;
    private static final int NO_DECREMENT = 0;
    private static final int DECREMENT_ON_SUCCESS = 1;
    private static final int DECREMENT_WITH_CERTAINTY = 2;
   public BasicResourcePool(ResourcePool.Manager mgr, int start, int min, int max, int inc, int num_acq_attempts, int acq_attempt_delay, 
            long check_idle_resources_delay, long max_resource_age, long max_idle_time, long excess_max_idle_time, long destroy_unreturned_resc_time, long expiration_enforcement_delay, boolean break_on_acquisition_failure, boolean debug_store_checkout_exceptions, 
            boolean force_synchronous_checkins, AsynchronousRunner taskRunner, RunnableQueue asyncEventQueue, Timer cullAndIdleRefurbishTimer, BasicResourcePoolFactory factory)
        throws ResourcePoolException
    {
        acquireWaiters = new HashSet();
        otherWaiters = new HashSet();
        managed = new HashMap();
        unused = new LinkedList();
        excluded = new HashSet();
        formerResources = new WeakHashMap();
        idleCheckResources = new HashSet();
        force_kill_acquires = false;
        broken = false;
        failed_checkins = 0L;
        failed_checkouts = 0L;
        failed_idle_tests = 0L;
        lastCheckinFailure = null;
        lastCheckoutFailure = null;
        lastIdleTestFailure = null;
        lastResourceTestFailure = null;
        lastAcquisitionFailiure = null;
        try
        {
            if(min > max)
            {
                if(logger.isLoggable(MLevel.WARNING))
                    logger.log(MLevel.WARNING, (new StringBuilder()).append("Bad pool size config, min ").append(min).append(" > max ").append(max).append(". Using ").append(max).append(" as min.").toString());
                min = max;
            }
            if(start < min)
            {
                if(logger.isLoggable(MLevel.WARNING))
                    logger.log(MLevel.WARNING, (new StringBuilder()).append("Bad pool size config, start ").append(start).append(" < min ").append(min).append(". Using ").append(min).append(" as start.").toString());
                start = min;
            }
            if(start > max)
            {
                if(logger.isLoggable(MLevel.WARNING))
                    logger.log(MLevel.WARNING, (new StringBuilder()).append("Bad pool size config, start ").append(start).append(" > max ").append(max).append(". Using ").append(max).append(" as start.").toString());
                start = max;
            }
            this.mgr = mgr;
            this.start = start;
            this.min = min;
            this.max = max;
            this.inc = inc;
            this.num_acq_attempts = num_acq_attempts;
            this.acq_attempt_delay = acq_attempt_delay;
            this.check_idle_resources_delay = check_idle_resources_delay;
            this.max_resource_age = max_resource_age;
            this.max_idle_time = max_idle_time;
            this.excess_max_idle_time = excess_max_idle_time;
            this.destroy_unreturned_resc_time = destroy_unreturned_resc_time;
            this.break_on_acquisition_failure = break_on_acquisition_failure;
            this.debug_store_checkout_exceptions = debug_store_checkout_exceptions && destroy_unreturned_resc_time > 0L;
            this.force_synchronous_checkins = force_synchronous_checkins;
            this.taskRunner = taskRunner;
            this.asyncEventQueue = asyncEventQueue;
            this.cullAndIdleRefurbishTimer = cullAndIdleRefurbishTimer;
            this.factory = factory;
            pending_acquires = 0;
            pending_removes = 0;
            target_pool_size = this.start;
            if(asyncEventQueue != null)
	        //资源库事件辅助工具-针对连接获取事件等
                rpes = new ResourcePoolEventSupport(this);
            else
                rpes = null;
	    //初始化连接资源
            ensureStartResources();
            if(mustEnforceExpiration())
            {
                if(expiration_enforcement_delay <= 0L)
                    this.expiration_enforcement_delay = automaticExpirationEnforcementDelay();
                else
                    this.expiration_enforcement_delay = expiration_enforcement_delay;
                cullTask = new CullTask();
                cullAndIdleRefurbishTimer.schedule(cullTask, minExpirationTime(), this.expiration_enforcement_delay);
            } else
            {
                this.expiration_enforcement_delay = expiration_enforcement_delay;
            }
            if(check_idle_resources_delay > 0L)
            {
                idleRefurbishTask = new CheckIdleResourcesTask();
                cullAndIdleRefurbishTimer.schedule(idleRefurbishTask, check_idle_resources_delay, check_idle_resources_delay);
            }
            if(logger.isLoggable(MLevel.FINER))
                logger.finer((new StringBuilder()).append(this).append(" config: [start -> ").append(this.start).append("; min -> ").append(this.min).append("; max -> ").append(this.max).append("; inc -> ").append(this.inc).append("; num_acq_attempts -> ").append(this.num_acq_attempts).append("; acq_attempt_delay -> ").append(this.acq_attempt_delay).append("; check_idle_resources_delay -> ").append(this.check_idle_resources_delay).append("; max_resource_age -> ").append(this.max_resource_age).append("; max_idle_time -> ").append(this.max_idle_time).append("; excess_max_idle_time -> ").append(this.excess_max_idle_time).append("; destroy_unreturned_resc_time -> ").append(this.destroy_unreturned_resc_time).append("; expiration_enforcement_delay -> ").append(this.expiration_enforcement_delay).append("; break_on_acquisition_failure -> ").append(this.break_on_acquisition_failure).append("; debug_store_checkout_exceptions -> ").append(this.debug_store_checkout_exceptions).append("; force_synchronous_checkins -> ").append(this.force_synchronous_checkins).append("]").toString());
        }
        catch(Exception e)
        {
            throw ResourcePoolUtils.convertThrowable(e);
        }
    }
 //初始化连接资源
ensureStartResources();
 private void ensureStartResources()
    {
        recheckResizePool();
    }
    //初始化线程池
     private synchronized void recheckResizePool()
    {
        _recheckResizePool();
    }
    //填充线程池
     private void _recheckResizePool()
    {
        if(!$assertionsDisabled && !Thread.holdsLock(this))
            throw new AssertionError();
        if(!broken)
        {
            int msz = managed.size();
            int shrink_count;
            int expand_count;
            if((shrink_count = msz - pending_removes - target_pool_size) > 0)
                shrinkPool(shrink_count);
            else
            if((expand_count = target_pool_size - (msz + pending_acquires)) > 0)
	        //委托给expandPool
                expandPool(expand_count);
        }
    }
在来看这个方法expandPool
    //初始化线程池
    private void expandPool(int count)
    {
        if(!$assertionsDisabled && !Thread.holdsLock(this))
            throw new AssertionError();
        if(USE_SCATTERED_ACQUIRE_TASK)
        {
            for(int i = 0; i < count; i++)
                taskRunner.postRunnable(new ScatteredAcquireTask());

        } else
        {
            for(int i = 0; i < count; i++)
	        //新建数据连接池获取线程AcquireTask,并交由taskRunner去调度
                taskRunner.postRunnable(new AcquireTask());

        }
    }

在来看AcquireTask
//数据库连接获取任务线程
//AcquireTask
class AcquireTask
        implements Runnable
    {

        public void run()
        {
            boolean decremented;
            boolean recheck;
            decremented = false;
            recheck = false;
            Exception lastException = null;
            for(int i = 0; shouldTry(i);)
                try
                {
                    if(i > 0)
                        Thread.sleep(acq_attempt_delay);
                    if(goodAttemptNumber(i + 1))
                    {
		        //关键在这个,获取连接
                        doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess();
                        decremented = true;
                    } else
                    {
                        decremented = true;
                        recheck = true;
                        doAcquireAndDecrementPendingAcquiresWithinLockAlways();
                    }
                    success = true;
                    continue;
                }                
            .....
            if(!decremented)
                decrementPendingAcquires();
        }
        boolean success;
        final BasicResourcePool this$0;

        public AcquireTask()
        {
            this.this$0 = BasicResourcePool.this;
            super();
            success = false;
            incrementPendingAcquires();
        }
}

//BasicResourcePool
//关键在这个,获取连接
doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess();
 private void doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess()
        throws Exception
    {
        doAcquire(1);
    }

    private void doAcquireAndDecrementPendingAcquiresWithinLockAlways()
        throws Exception
    {
        doAcquire(2);
    }

    private void doAcquire(int decrement_policy)
        throws Exception
    {
        Object resc;
        if(!$assertionsDisabled && Thread.holdsLock(this))
            throw new AssertionError();
	//获取连接池,这个有点深,在C3P0PooledConnectionPool的构造方法中,
	//资源池工厂创建资源池,其中mgr为C3P0PooledConnectionPool构造方法中的
	//内部类
        resc = mgr.acquireResource();
        boolean destroy = false;
        BasicResourcePool basicresourcepool = this;
        JVM INSTR monitorenter ;
        int msz = managed.size();
        if(!broken && msz < target_pool_size)
	//将数据库连接资源添加到BasicResourcePool的数据源数据连接池中unused,LinkedList<Connection>
            assimilateResource(resc);
        else
            destroy = true;
        if(decrement_policy == 1)
            _decrementPendingAcquires();
        if(decrement_policy == 2)
            _decrementPendingAcquires();
        break MISSING_BLOCK_LABEL_108;
    }

我们来看这句
 resc = mgr.acquireResource();

//_cls1PooledConnectionResourcePoolManager
 class _cls1PooledConnectionResourcePoolManager
                implements com.mchange.v2.resourcepool.ResourcePool.Manager
            {

                public Object acquireResource()
                    throws Exception
                {
                    PooledConnection out;
                    Exception e;
                    if(connectionCustomizer == null)
                        out = auth.equals(C3P0ImplUtils.NULL_AUTH) ? cpds.getPooledConnection() : cpds.getPooledConnection(auth.getUser(), auth.getPassword());
                    else
                        try
                        {
			     //看到这句是不是想到了什么,他妈的终于和WrapperConnectionPoolDataSourceBase
			     //连接起来了,这是我们前面讲的
                            WrapperConnectionPoolDataSourceBase wcpds = (WrapperConnectionPoolDataSourceBase)cpds;
                            //从数据库连接池包装类,获取数据库连接池
                            out = auth.equals(C3P0ImplUtils.NULL_AUTH) ? wcpds.getPooledConnection(connectionCustomizer, parentDataSourceIdentityToken) : wcpds.getPooledConnection(auth.getUser(), auth.getPassword(), connectionCustomizer, parentDataSourceIdentityToken);
                        }
                    Connection con;
                    if(scache != null)
                        if(c3p0PooledConnections)
                            ((AbstractC3P0PooledConnection)out).initStatementCache(scache);
                        else
                            C3P0PooledConnectionPool.logger.warning("StatementPooling not implemented for external (non-c3p0) ConnectionPoolDataSources.");
                    con = null;
                    waitMarkPooledConnectionInUse(out);
		    //从连接池获取连接
                    con = out.getConnection();
                    ConnectionUtils.attemptClose(con);
                    unmarkPooledConnectionInUse(out);
                    PooledConnection pooledconnection = out;
                    return pooledconnection;
                }
}

在来看WrapperConnectionPoolDataSource
//WrapperConnectionPoolDataSource
//获取数据源连接池
 public PooledConnection getPooledConnection()
        throws SQLException
    {
        return getPooledConnection((ConnectionCustomizer)null, null);
    }
    protected PooledConnection getPooledConnection(ConnectionCustomizer cc, String pdsIdt)
        throws SQLException
    {
        DataSource nds;
        Connection conn;
	//获取DriverManagerDataSource
        nds = getNestedDataSource();
        if(nds == null)
            throw new SQLException("No standard DataSource has been set beneath this wrapper! [ nestedDataSource == null ]");
        conn = null;
	//委托给DriverManagerDataSource
        conn = nds.getConnection();
        return new NewPooledConnection(conn, connectionTester, isAutoCommitOnClose(getUser()), isForceIgnoreUnresolvedTransactions(getUser()), getPreferredTestQuery(getUser()), cc, pdsIdt);
    }

在来看DriverManagerDataSource
//DriverManagerDataSource
//获取连接
public Connection getConnection()
        throws SQLException
    {
        ensureDriverLoaded();
	//从驱动器,获取连接,不同的驱动返回不同的数据库连接实现
        Connection out = driver().connect(jdbcUrl, properties);
        if(out == null)
            throw new SQLException((new StringBuilder()).append("Apparently, jdbc URL '").append(jdbcUrl).append("' is not valid for the underlying ").append("driver [").append(driver()).append("].").toString());
        else
            return out;
    }

回到BasicResourcePool的数据库连接获取方法doAcquire的这一句
//将数据库连接资源添加到BasicResourcePool的数据源数据连接池中unused,LinkedList<Connection>
assimilateResource(resc);
 private void assimilateResource(Object resc)
        throws Exception
    {
        if(!$assertionsDisabled && !Thread.holdsLock(this))
            throw new AssertionError();
        managed.put(resc, new PunchCard());
	//将获取数据库连接,添加到BasicResourcePool的unused集合中,
        unused.add(0, resc);
        asyncFireResourceAcquired(resc, managed.size(), unused.size(), excluded.size());
        notifyAll();
        trace();
        if(exampleResource == null)
            exampleResource = resc;
    }

自此getPool方法的内容讲解完毕,这段内容有点多,脑栈太深,这里我们总结一下:
所有的这些都是从这句话开始AbstractPoolBackedDataSource的获取getConnection方法的
PooledConnection pc = getPoolManager().getPool().checkoutPooledConnection();
getPoolManager()方法,getPoolManager()实际上,是初始化数据库连接池管理器C3P0PooledConnectionPoolManager,初始化C3P0PooledConnectionPoolManager的ConnectionPoolDataSource(WrapperConnectionPoolDataSource)及定时任务调度器,及死锁检测线程,及延时死锁检测线程。getPool()方法实际上,首先初始化C3P0PooledConnectionPool
,在初始化C3P0PooledConnectionPool过程中,通过BasicResourcePoolFactory创建资源池,BasicResourcePool;在初始化资源资源池时,根据数据库连接池的大小,创建相应的数据库连接获取线程AcquireTask,并将线程添加到
ThreadPoolAsynchronousRunner的待调度线程队列pendingTasks,LinkedList<Runnable>中;而数据库连接线程获取连接是通过C3P0PooledConnectionPool的内部类_cls1PooledConnectionResourcePoolManager的资源获取方法
acquireResource,acquireResource实际上是从通过WrapperConnectionPoolDataSource获取数据库连接池NewPooledConnection,NewPooledConnection的构造中有一个数据库连接Connection,Connection实际上是通过DriverManagerDataSource调用driver的connect方法获取;AcquireTask获取连接之后,添加到BasicResourcePool的unused,LinkList<PooledConnection>集合中。

回到,AbstractPoolBackedDataSource的获取getConnection方法的这句
PooledConnection pc = getPoolManager().getPool().checkoutPooledConnection();

看第三点.checkoutPooledConnection()
PooledConnection pc = getPoolManager().getPool().checkoutPooledConnection();


//C3P0PooledConnectionPool

public PooledConnection checkoutPooledConnection()
        throws SQLException
    {
        PooledConnection pc;
        pc = (PooledConnection)checkoutAndMarkConnectionInUse();
        pc.addConnectionEventListener(cl);
        return pc;
    }
      private Object checkoutAndMarkConnectionInUse()
        throws TimeoutException, CannotAcquireResourceException, ResourcePoolException, InterruptedException
    {
        Object out;
        boolean success;
        out = null;
        success = false;
        if(success)
            break; /* Loop/switch isn't completed */
	//从资源池BasicResourcePool中,获取连接,
        out = rp.checkoutResource(checkoutTimeout);
        if(out instanceof AbstractC3P0PooledConnection)
        {
            AbstractC3P0PooledConnection acpc = (AbstractC3P0PooledConnection)out;
            Connection physicalConnection = acpc.getPhysicalConnection();
            success = tryMarkPhysicalConnectionInUse(physicalConnection);
        } 
        return out;
    }

//BasicResourcePool
//从资源池获取数据库连接池
 public Object checkoutResource(long timeout)
        throws TimeoutException, ResourcePoolException, InterruptedException
    {
        Object resc;
	//委托给prelimCheckoutResource,如何资源池中有数据库连接池,直接返回unused.get(0)
        resc = prelimCheckoutResource(timeout);
        boolean refurb = attemptRefurbishResourceOnCheckout(resc);
	synchronized(this)
        {
            if(!refurb)
            {
                if(logger.isLoggable(MLevel.FINER))
                    logger.log(MLevel.FINER, (new StringBuilder()).append("Resource [").append(resc).append("] could not be refurbished in preparation for checkout. Will try to find a better resource.").toString());
                removeResource(resc);
                ensureMinResources();
                resc = null;
            } else
            {
	        //如果资源池中有数据库连接池,则委托给asyncFireResourceCheckedOut,
		//并创建定时任务线程,交由ThreadPoolAsynchronousRunner去调度
                asyncFireResourceCheckedOut(resc, managed.size(), unused.size(), excluded.size());
                trace();
                PunchCard card = (PunchCard)managed.get(resc);
                if(card == null)
                {
                    if(logger.isLoggable(MLevel.FINER))
                        logger.finer((new StringBuilder()).append("Resource ").append(resc).append(" was removed from the pool while it was being checked out ").append(" or refurbished for checkout. Will try to find a replacement resource.").toString());
                    resc = null;
                } else
                {
                    card.checkout_time = System.currentTimeMillis();
                    if(debug_store_checkout_exceptions)
                        card.checkoutStackTraceException = new Exception("DEBUG STACK TRACE: Overdue resource check-out stack trace.");
                }
            }
        }
        if(resc == null)
            return checkoutResource(timeout);
        return resc;
    }
//如何资源池中有数据库连接池,直接返回unused.get(0)
private synchronized Object prelimCheckoutResource(long timeout)
        throws TimeoutException, ResourcePoolException, InterruptedException
    {
        Object resc;
        Thread t;
        ensureNotBroken();
	//LinkedList unused;
        int available = unused.size();
        if(available == 0)
        {
	    //
            int msz = managed.size();
            if(msz < max)
            {
                int desired_target = msz + acquireWaiters.size() + 1;
                if(logger.isLoggable(MLevel.FINER))
                    logger.log(MLevel.FINER, (new StringBuilder()).append("acquire test -- pool size: ").append(msz).append("; target_pool_size: ").append(target_pool_size).append("; desired target? ").append(desired_target).toString());
                if(desired_target >= target_pool_size)
                {
                    desired_target = Math.max(desired_target, target_pool_size + inc);
                    target_pool_size = Math.max(Math.min(max, desired_target), min);
                    _recheckResizePool();
                }
            } else
            if(logger.isLoggable(MLevel.FINER))
                logger.log(MLevel.FINER, (new StringBuilder()).append("acquire test -- pool is already maxed out. [managed: ").append(msz).append("; max: ").append(max).append("]").toString());
            awaitAvailable(timeout);
        }
	//这里关键,从BasicResourcePool的资源池unused,LinkedList<PooledConnection>中,获取数据库连接池
        resc = unused.get(0);
        if(!idleCheckResources.contains(resc))
            break MISSING_BLOCK_LABEL_365;
        t = Thread.currentThread();
        otherWaiters.add(t);
        wait(timeout);
        ensureNotBroken();
        otherWaiters.remove(t);
        break MISSING_BLOCK_LABEL_359;
        otherWaiters.remove(t);
        removeResource(resc);
        ensureMinResources();
        unused.remove(0);
        return resc;
    }

如果资源池中,没有有数据库连接池,创建数据连接池获取线程,并交由
ThreadPoolAsynchronousRunner去调度。
private void asyncFireResourceCheckedOut(final Object resc, final int pool_size, final int available_size, final int removed_but_unreturned_size)
    {
        if(canFireEvents())
        {
            Runnable r = new Runnable() {

                public void run()
                {
		    //线程工作委托给ResourcePoolEventSupport的fireResourceCheckedOut方法
		    //激发数据连接池获取事件,由对应监听器的去处理
		    //ResourcePoolEventSupport rpes
                    rpes.fireResourceCheckedOut(resc, pool_size, available_size, removed_but_unreturned_size);
                }

                final Object val$resc;
                final int val$pool_size;
                final int val$available_size;
                final int val$removed_but_unreturned_size;
                final BasicResourcePool this$0;

            
            {
                this.this$0 = BasicResourcePool.this;
                resc = obj;
                pool_size = i;
                available_size = j;
                removed_but_unreturned_size = k;
                super();
            }
            };
	    //关键在这
            asyncEventQueue.postRunnable(r);
        }
    }

//ThreadPoolAsynchronousRunner
public synchronized void postRunnable(Runnable runnable)
    {
        try
        {
	   //LinkedList pendingTasks;LinkedList<Runnable>;
	   //如果资源池中,没有有数据库连接池,
	   //则建立连接获取线程,添加调度器的待调度定时任务pendingTasks列表中
            pendingTasks.add(runnable);
            notifyAll();
            if(logger.isLoggable(MLevel.FINEST))
                logger.log(MLevel.FINEST, (new StringBuilder()).append(this).append(": Adding task to queue -- ").append(runnable).toString());
        }
    }

再来看
//线程工作委托给ResourcePoolEventSupport的fireResourceCheckedOut方法
//激发获取数据库连接事件,由资源连接池监听器的去处理
rpes.fireResourceCheckedOut(resc, pool_size, available_size, removed_but_unreturned_size);

//ResourcePoolEventSupport
public class ResourcePoolEventSupport
{
 public synchronized void fireResourceCheckedOut(Object resc, int pool_size, int available_size, int removed_but_unreturned_size)
    {
        if(!mlisteners.isEmpty())
        {
            ResourcePoolEvent evt = new ResourcePoolEvent(source, resc, true, pool_size, available_size, removed_but_unreturned_size);
            ResourcePoolListener rpl;
	    //遍历资源连接池监听器,获取数据库连接资源
            for(Iterator i = mlisteners.iterator(); i.hasNext(); rpl.resourceCheckedOut(evt))
                rpl = (ResourcePoolListener)i.next();

        }
    }
}

从上面一段分析,可以看出checkoutPooledConnection()方法,实际上是从
BasicResourcePool的资源池unused,LinkedList<PooledConnection>中,获取数据库连接池;
如果没有,则创建数据库连接池获取事件触发线程,并交由ThreadPoolAsynchronousRunner去调度;数据库连接池获取事件触发线程主要是通过ResourcePoolEventSupport触发数据库连接池获取事件,交给相关监听器处理。
自此下面这句话终于讲完了。
PooledConnection pc = getPoolManager().getPool().checkoutPooledConnection();

这里,做个小结:
getPoolManager()方法,getPoolManager()实际上,是初始化数据库连接池管理器C3P0PooledConnectionPoolManager,初始化C3P0PooledConnectionPoolManager的ConnectionPoolDataSource(WrapperConnectionPoolDataSource)及定时任务调度器,及死锁检测线程,及延时死锁检测线程。getPool()方法实际上,首先初始化C3P0PooledConnectionPool
,在初始化C3P0PooledConnectionPool过程中,通过BasicResourcePoolFactory创建资源池,BasicResourcePool;在初始化资源资源池时,根据数据库连接池的大小,创建相应的数据库连接获取线程AcquireTask,并将线程添加到
ThreadPoolAsynchronousRunner(Timer)的待调度线程队列pendingTasks,LinkedList<Runnable>中;而数据库连接线程获取
连接是通过C3P0PooledConnectionPool的内部类_cls1PooledConnectionResourcePoolManager的资源获取方法
acquireResource,acquireResource实际上是从通过WrapperConnectionPoolDataSource获取数据库连接池NewPooledConnection,NewPooledConnection的构造中有一个数据库连接Connection,Connection实际上是通过DriverManagerDataSource调用driver的connect方法获取;AcquireTask获取连接之后,添加到BasicResourcePool的unused,LinkList<PooledConnection>集合中。
checkoutPooledConnection()方法,实际上是从BasicResourcePool的资源池unused,LinkedList<PooledConnection>中,获取数据库连接池;
如果没有,则创建数据库连接池获取事件触发线程,并交由ThreadPoolAsynchronousRunner去调度;数据库连接池获取事件触发线程主要是通过ResourcePoolEventSupport触发数据库连接池获取事件,交给相关监听器处理。


回到AbstractPoolBackedDataSource的获取连接方法,
public abstract class AbstractPoolBackedDataSource extends PoolBackedDataSourceBase
    implements PooledDataSource
{
    public Connection getConnection()
        throws SQLException
    {
         //获取数据库连接池,实际为NewPooledConnection
        PooledConnection pc = getPoolManager().getPool().checkoutPooledConnection();
	//从数据库连接池,返回数据库连接
        return pc.getConnection();
    }
}

 PooledConnection pc = getPoolManager().getPool().checkoutPooledConnection();

这句话实际调用的返回的是NewPooledConnection
//WrapperConnectionPoolDataSource
protected PooledConnection getPooledConnection(ConnectionCustomizer cc, String pdsIdt)
        throws SQLException
    {
        DataSource nds;
        Connection conn;
        nds = getNestedDataSource();
        conn = null;
        conn = nds.getConnection();
        return new NewPooledConnection(conn, connectionTester, isAutoCommitOnClose(getUser()), isForceIgnoreUnresolvedTransactions(getUser()), getPreferredTestQuery(getUser()), cc, pdsIdt);
    }

来看这一句
//从数据库连接池,返回数据库连接
return pc.getConnection();

在上面获取数据库连接池中,实际上返回的是NewPooledConnection,我们来看一下NewPooledConnection
//NewPooledConnection

这一篇,内容讲的有点多,NewPooledConnection我们下一篇在讲

//DbAuth
public final class DbAuth
    implements Serializable
{

    public DbAuth(String username, String password)
    {
        this.username = username;
        this.password = password;
    }

    public String getUser()
    {
        return username;
    }

    public String getPassword()
    {
        return password;
    }

    public String getMaskedUserString()
    {
        return getMaskedUserString(2, 8);
    }

    private String getMaskedUserString(int chars_to_reveal, int total_chars)
    {
        if(username == null)
            return "null";
        StringBuffer sb = new StringBuffer(32);
        if(username.length() >= chars_to_reveal)
        {
            sb.append(username.substring(0, chars_to_reveal));
            int i = 0;
            for(int len = total_chars - chars_to_reveal; i < len; i++)
                sb.append('*');

        } else
        {
            sb.append(username);
        }
        return sb.toString();
    }

    public boolean equals(Object o)
    {
        if(this == o)
            return true;
        if(o != null && getClass() == o.getClass())
        {
            DbAuth other = (DbAuth)o;
            return ObjectUtils.eqOrBothNull(username, other.username) && ObjectUtils.eqOrBothNull(password, other.password);
        } else
        {
            return false;
        }
    }

    public int hashCode()
    {
        return ObjectUtils.hashOrZero(username) ^ ObjectUtils.hashOrZero(password);
    }

    private void writeObject(ObjectOutputStream out)
        throws IOException
    {
        out.writeShort(1);
        out.writeObject(username);
        out.writeObject(password);
    }

    private void readObject(ObjectInputStream in)
        throws IOException, ClassNotFoundException
    {
        short version = in.readShort();
        switch(version)
        {
        case 1: // '\001'
            username = (String)in.readObject();
            password = (String)in.readObject();
            break;

        default:
            throw new UnsupportedVersionException(this, version);
        }
    }

    transient String username;
    transient String password;
    static final long serialVersionUID = 1L;
    private static final short VERSION = 1;
}

ThreadPoolAsynchronousRunner思想的关键在Timer,TimerTask
//ThreadPoolAsynchronousRunner
public final class ThreadPoolAsynchronousRunner
    implements AsynchronousRunner
{
    int deadlock_detector_interval;//死锁检测间隔
    int interrupt_delay_after_apparent_deadlock;
    int max_individual_task_time;
    int num_threads;//线程数
    boolean daemon;
    HashSet managed;
    HashSet available;
    LinkedList pendingTasks;
    Random rnd;
    Timer myTimer;
    boolean should_cancel_timer;
    TimerTask deadlockDetector;//死锁检测定时任务
    TimerTask replacedThreadInterruptor;//线程中断重启定时任务
    Map stoppedThreadsToStopDates;
    String threadLabel;
    private ThreadPoolAsynchronousRunner(int i, boolean flag, int j, int k, int l, Timer timer, boolean flag1, 
            String s)
    {
        rnd = new Random();
        deadlockDetector = new DeadlockDetector();//死锁检测定时任务
        replacedThreadInterruptor = null;
        stoppedThreadsToStopDates = new HashMap();
        num_threads = i;
        daemon = flag;
        max_individual_task_time = j;
        deadlock_detector_interval = k;
        interrupt_delay_after_apparent_deadlock = l;
        myTimer = timer;
        should_cancel_timer = flag1;
        threadLabel = s;
        recreateThreadsAndTasks();
        timer.schedule(deadlockDetector, k, k);//调度死锁任务
    }
    //死锁检测定时任务
     class DeadlockDetector extends TimerTask
    {

        public void run()
        {
            boolean flag;
label0:
            {
                flag = false;
                synchronized(ThreadPoolAsynchronousRunner.this)
                {
                    if(pendingTasks.size() != 0)
                        break label0;
                    last = null;
                    if(ThreadPoolAsynchronousRunner.logger.isLoggable(MLevel.FINEST))
                        ThreadPoolAsynchronousRunner.logger.log(MLevel.FINEST, (new StringBuilder()).append(this).append(" -- Running DeadlockDetector[Exiting. No pending tasks.]").toString());
                }
                return;
            }
            current = (LinkedList)pendingTasks.clone();
            if(ThreadPoolAsynchronousRunner.logger.isLoggable(MLevel.FINEST))
                ThreadPoolAsynchronousRunner.logger.log(MLevel.FINEST, (new StringBuilder()).append(this).append(" -- Running DeadlockDetector[last->").append(last).append(",current->").append(current).append(']').toString());
            if(current.equals(last))
            {
                if(ThreadPoolAsynchronousRunner.logger.isLoggable(MLevel.WARNING))
                {
                    ThreadPoolAsynchronousRunner.logger.warning((new StringBuilder()).append(this).append(" -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!").toString());
                    StringWriter stringwriter = new StringWriter(4096);
                    PrintWriter printwriter = new PrintWriter(stringwriter);
                    printwriter.print(this);
                    printwriter.println(" -- APPARENT DEADLOCK!!! Complete Status: ");
                    printwriter.print(getMultiLineStatusString(1));
                    printwriter.println("Pool thread stack traces:");
                    String s = getStackTraces(1);
                    if(s == null)
                        printwriter.println("\t[Stack traces of deadlocked task threads not available.]");
                    else
                        printwriter.print(s);
                    printwriter.flush();
                    ThreadPoolAsynchronousRunner.logger.warning(stringwriter.toString());
                    printwriter.close();
                }
                if(ThreadPoolAsynchronousRunner.logger.isLoggable(MLevel.FINEST))
                {
                    StringWriter stringwriter1 = new StringWriter(4096);
                    PrintWriter printwriter1 = new PrintWriter(stringwriter1);
                    printwriter1.print(this);
                    printwriter1.println(" -- APPARENT DEADLOCK extra info, full JVM thread dump: ");
                    String s1 = getJvmStackTraces(1);
                    if(s1 == null)
                        printwriter1.println("\t[Full JVM thread dump not available.]");
                    else
                        printwriter1.print(s1);
                    printwriter1.flush();
                    ThreadPoolAsynchronousRunner.logger.finest(stringwriter1.toString());
                    printwriter1.close();
                }
                recreateThreadsAndTasks();
                flag = true;
            }
            threadpoolasynchronousrunner;
            JVM INSTR monitorexit ;
              goto _L1
            exception;
            throw exception;
_L1:
            if(flag)
            {
                ThreadPerTaskAsynchronousRunner threadpertaskasynchronousrunner = new ThreadPerTaskAsynchronousRunner(10, max_individual_task_time);
                for(Iterator iterator = current.iterator(); iterator.hasNext(); threadpertaskasynchronousrunner.postRunnable((Runnable)iterator.next()));
                threadpertaskasynchronousrunner.close(false);
                last = null;
            } else
            {
                last = current;
            }
            current = null;
            return;
        }

        LinkedList last;
        LinkedList current;
        final ThreadPoolAsynchronousRunner this$0;

        DeadlockDetector()
        {
            this$0 = ThreadPoolAsynchronousRunner.this;
            super();
            last = null;
            current = null;
        }
    }
    //线程池
    class PoolThread extends Thread
    {

        public int getIndex()
        {
            return index;
        }

        void gentleStop()
        {
            should_stop = true;
        }

        Runnable getCurrentTask()
        {
            return currentTask;
        }

        private void setMaxIndividualTaskTimeEnforcer()
        {
	    //
            maxIndividualTaskTimeEnforcer = new MaxIndividualTaskTimeEnforcer(this);
            myTimer.schedule(maxIndividualTaskTimeEnforcer, max_individual_task_time);
        }

        private void cancelMaxIndividualTaskTimeEnforcer()
        {
            maxIndividualTaskTimeEnforcer.cancel();
            maxIndividualTaskTimeEnforcer = null;
        }

        private void purgeTimer()
        {
            myTimer.purge();
            if(ThreadPoolAsynchronousRunner.logger.isLoggable(MLevel.FINER))
                ThreadPoolAsynchronousRunner.logger.log(MLevel.FINER, (new StringBuilder()).append(getClass().getName()).append(" -- PURGING TIMER").toString());
        }

        public void run()
        {
            long l = rnd.nextLong();
_L2:
            Runnable runnable;
label0:
            {
                synchronized(ThreadPoolAsynchronousRunner.this)
                {
                    for(; !should_stop && pendingTasks.size() == 0; wait(5000L));
                    if(!should_stop)
                        break label0;
                }
                break MISSING_BLOCK_LABEL_562;
            }
            if(!available.remove(this))
                throw new InternalError("An unavailable PoolThread tried to check itself out!!!");
            runnable = (Runnable)pendingTasks.remove(0);
            currentTask = runnable;
            threadpoolasynchronousrunner2;
            JVM INSTR monitorexit ;
            break MISSING_BLOCK_LABEL_123;
            if(max_individual_task_time > 0)
                setMaxIndividualTaskTimeEnforcer();
            runnable.run();
label1:
            {
                if(maxIndividualTaskTimeEnforcer != null)
                {
                    cancelMaxIndividualTaskTimeEnforcer();
                    l ^= l << 21;
                    l ^= l >>> 35;
                    l ^= l << 4;
                    if(l % 500L == 0L)
                        purgeTimer();
                }
                synchronized(ThreadPoolAsynchronousRunner.this)
                {
                    if(!should_stop)
                        break label1;
                }
                break MISSING_BLOCK_LABEL_562;
            }
            if(available != null && !available.add(this))
                throw new InternalError("An apparently available PoolThread tried to check itself in!!!");
            currentTask = null;
            threadpoolasynchronousrunner3;
            JVM INSTR monitorexit ;
            continue; /* Loop/switch isn't completed */
            RuntimeException runtimeexception;
            runtimeexception;
            if(ThreadPoolAsynchronousRunner.logger.isLoggable(MLevel.WARNING))
                ThreadPoolAsynchronousRunner.logger.log(MLevel.WARNING, (new StringBuilder()).append(this).append(" -- caught unexpected Exception while executing posted task.").toString(), runtimeexception);
label2:
            {
                if(maxIndividualTaskTimeEnforcer != null)
                {
                    cancelMaxIndividualTaskTimeEnforcer();
                    l ^= l << 21;
                    l ^= l >>> 35;
                    l ^= l << 4;
                    if(l % 500L == 0L)
                        purgeTimer();
                }
                synchronized(ThreadPoolAsynchronousRunner.this)
                {
                    if(!should_stop)
                        break label2;
                }
                break MISSING_BLOCK_LABEL_562;
            }
            if(available != null && !available.add(this))
                throw new InternalError("An apparently available PoolThread tried to check itself in!!!");
            currentTask = null;
            threadpoolasynchronousrunner4;
            JVM INSTR monitorexit ;
            if(true) goto _L2; else goto _L1
_L1:
            Exception exception3;
            exception3;
label3:
            {
                if(maxIndividualTaskTimeEnforcer != null)
                {
                    cancelMaxIndividualTaskTimeEnforcer();
                    l ^= l << 21;
                    l ^= l >>> 35;
                    l ^= l << 4;
                    if(l % 500L == 0L)
                        purgeTimer();
                }
                synchronized(ThreadPoolAsynchronousRunner.this)
                {
                    if(!should_stop)
                        break label3;
                }
                break MISSING_BLOCK_LABEL_562;
            }
            if(available != null && !available.add(this))
                throw new InternalError("An apparently available PoolThread tried to check itself in!!!");
            currentTask = null;
            threadpoolasynchronousrunner5;
            JVM INSTR monitorexit ;
            throw exception3;
            synchronized(ThreadPoolAsynchronousRunner.this)
            {
                shuttingDown(this);
            }
            break MISSING_BLOCK_LABEL_759;
            Object obj;
            obj;
            synchronized(ThreadPoolAsynchronousRunner.this)
            {
                shuttingDown(this);
            }
            break MISSING_BLOCK_LABEL_759;
            threadpoolasynchronousrunner1;
            if(ThreadPoolAsynchronousRunner.logger.isLoggable(MLevel.WARNING))
                ThreadPoolAsynchronousRunner.logger.log(MLevel.WARNING, (new StringBuilder()).append("An unexpected RuntimException is implicated in the closing of ").append(this).toString(), threadpoolasynchronousrunner1);
            throw threadpoolasynchronousrunner1;
            threadpoolasynchronousrunner1;
            if(ThreadPoolAsynchronousRunner.logger.isLoggable(MLevel.WARNING))
                ThreadPoolAsynchronousRunner.logger.log(MLevel.WARNING, (new StringBuilder()).append("An Error forced the closing of ").append(this).append(". Will attempt to reconstruct, but this might mean that something bad is happening.").toString(), threadpoolasynchronousrunner1);
            throw threadpoolasynchronousrunner1;
            Exception exception7;
            exception7;
            synchronized(ThreadPoolAsynchronousRunner.this)
            {
                shuttingDown(this);
            }
            throw exception7;
        }

        Runnable currentTask;
        boolean should_stop;
        int index;
        TimerTask maxIndividualTaskTimeEnforcer;
        final ThreadPoolAsynchronousRunner this$0;

        PoolThread(int i, boolean flag)
        {
            this$0 = ThreadPoolAsynchronousRunner.this;
            super();
            maxIndividualTaskTimeEnforcer = null;
            setName((new StringBuilder()).append(threadLabel != null ? threadLabel : getClass().getName()).append("-#").append(i).toString());
            setDaemon(flag);
            index = i;
        }
    }
}
5
0
分享到:
评论

相关推荐

    开源数据库连接池c3p0

    开源数据库连接池c3p0是一款广泛应用于Java后端开发中的数据库连接管理工具,它能够有效地管理和优化数据库连接,提高应用的性能和响应速度。c3p0的主要功能包括连接池的创建、维护以及自动回收资源,使得多个并发...

    c3p0数据库连接池案例

    **c3p0数据库连接池案例** 在Java开发中,数据库连接池是管理数据库连接的重要工具,它能够有效地提高数据库操作的效率并节省系统资源。C3P0是一款开源的数据库连接池组件,由Maurice Priess创建,被广泛应用于各种...

    c3p0数据库连接池

    **c3p0数据库连接池**是Java后端开发中常用的一个开源的数据库连接池组件,主要用于管理和优化数据库连接。它的全称是ComMchange V3 Pooled Database Connections,由Maurice Priess创建,旨在提供一个高效、灵活且...

    数据库连接池C3P0.zip

    在本压缩包“数据库连接池C3P0.zip”中,包含了C3P0数据库连接池的相关jar包以及配置文件,用于帮助开发者集成到他们的Java应用中,特别是与MYSQL数据库配合使用。 C3P0的主要特性包括: 1. **连接池管理**:C3P0...

    C3P0数据库连接池jar包(完整版)

    C3P0数据库连接池是Java开发中常用的一个开源组件,它主要用于管理数据库连接,以提高应用程序处理数据库的效率和性能。C3P0是由Mithral Software公司开发的,其全称为Comerica Commercial Connection Pool,是一款...

    数据库连接池c3p0所需jar包

    - **commons-pool**:Apache Commons Pool是通用的对象池服务,可以用于创建各种资源的池化,包括C3P0在内的数据库连接池在底层使用了这个库来实现对象的管理和复用。 在实际开发中,你通常会将这些JAR包添加到项目...

    数据库连接池C3P0,jar包

    1. **连接池管理**:C3P0能够创建和维护一个数据库连接池,根据预设的参数动态调整连接池大小,以满足应用需求。 2. **自动检测与恢复**:C3P0会定期检查连接的有效性,如果发现死锁或其他问题,它可以自动回收并...

    C3p0数据库连接池

    **C3p0数据库连接池**是开源的Java数据库连接池工具,主要用于管理数据库连接,提高应用程序处理数据库的效率。C3p0是由Miquel Arroyo开发的一个轻量级、高性能的连接池实现,它能够帮助Java应用程序在处理数据库...

    c3p0连接池jar包

    C3P0连接池是Java开发中常用的数据库连接池组件,它能够有效地管理和优化数据库连接,提高应用程序的性能和效率。C3P0由Mithun Das Laskar创建,是一个开源项目,广泛应用于各种Java Web应用中。下面将详细介绍C3P0...

    hibernate c3p0 数据库连接池参数详解.txt

    ### Hibernate C3P0 数据库连接池参数详解 在企业级应用开发中,数据库连接池技术扮演着极其重要的角色,它能显著提高系统的性能并优化资源管理。Hibernate 作为 Java 领域中最流行的 ORM(对象关系映射)框架之一...

    JAVA数据库连接池

    本教程将深入探讨数据库连接池的原理,特别是针对C3P0和DBCP这两个常见的连接池实现。 首先,我们来看一下数据库连接池的基本概念。数据库连接池在初始化时会创建一定数量的数据库连接并保存在池中,当应用程序需要...

    C3P0 连接池源码

    C3P0数据库连接池是Java开发中广泛使用的开源组件,用于管理数据库连接,提高数据库访问效率并降低系统资源消耗。源代码分析可以帮助我们深入理解其内部机制,从而更好地优化和配置C3P0,提升应用程序性能。 1. **...

    tomcat6+jndi+c3p0配置数据库连接池

    本示例主要讲解如何在Tomcat6中结合JNDI(Java Naming and Directory Interface)和C3P0库来配置数据库连接池,这对于初学者理解Web应用服务器与数据库的交互方式具有很大帮助。 首先,C3P0是一个开源的JDBC连接池...

    C3P0数据库连接池

    **C3P0数据库连接池** 是一个开源的Java数据库连接池组件,它为应用程序提供了一种管理和控制数据库连接的方法,以实现高效、稳定的数据库访问。C3P0的主要目标是提高应用程序的性能,减少数据库资源的消耗,通过在...

    c3p0连接池工具

    总之,c3p0连接池是Java应用中管理数据库连接的有效工具,通过合理配置和使用,可以显著提高系统的运行效率和稳定性。在实际开发中,应结合具体项目需求选择合适的连接池,并进行持续监控和优化。

    HibernateC3P0 数据库连接池架包.rar

    C3P0是由M-Fabrice Remy创建的,它是一个完全实现了JDBC3规范的数据库连接池实现,具有自动测试连接、自动关闭无效连接等功能,显著提高了数据库操作的性能。 二、C3P0核心特性 1. 连接池的初始化和最大连接数:C3...

    c3p0-0.9.5.2连接池所需jar包

    数据库连接池在初始化时会创建一定数量的数据库连接,并将它们保存在一个池中。当应用程序需要访问数据库时,不是直接创建新的连接,而是从连接池中获取一个已经存在的连接。使用完毕后,连接会返回到池中,而不是...

    c3p0连接池插件

    作为一个数据库连接池,c3p0的主要作用在于管理数据库连接,以提高应用程序的性能和效率。在高并发的Web应用中,频繁地创建和销毁数据库连接会消耗大量资源,而c3p0通过复用已存在的连接,避免了这种开销。 **一、...

Global site tag (gtag.js) - Google Analytics