DruidDataSource源碼分析


最近公司要求基於阿里的DruidDataSource來做一個連接池監控 , 正好之前沒有看過DruidDataSource的源碼 , 便自己看了四個多小時寫了一些自己的理解 , 給大家分享一下 , 如果有什么錯誤 , 歡迎指出!!!

 

DruidDataSource主要用到的是ReentrantLock鎖,還有 notEmpty empty兩個條件,生產連接與消費連接的線程在兩個條件上等待與喚醒。


1創建連接

    連接太多了的時候,在empty條件上等待,就是等空了再運行

 1 // 防止創建超過maxActive數量的連接
 2 if (activeCount + poolingCount >= maxActive) {
 3     empty.await();
 4     continue;
 5 }
 6 
 7 connection = createPhysicalConnection();
 8 setFailContinuous(false);
 9 
10 boolean result = put(connection);


    后面是創建一個物理連接,然后put一下,這個put是放池子中,主要下面幾句:

1 holder = new DruidConnectionHolder(DruidDataSource.this, physicalConnectionInfo);
2 connections[poolingCount] = holder;
3 incrementPoolingCount();
4 notEmpty.signal();
5 notEmptySignalCount++;

   
2使用連接

    DruidConnectionHolder takeLast()之中,當poolingCount中數量為0時等待。
    正好說明使用連接的線程,當連接沒有時,就等待。如果池中有連接就執行下面的語句:

1 decrementPoolingCount();
2 DruidConnectionHolder last = connections[poolingCount];//拿走池中最后一個
3 connections[poolingCount] = null;//最后一個賦值成null


    獲取鏈接的主要方法getPooledConnection()中調用takeLast(),又調用getConnection(),
    這里面又是插入了過濾鏈來統計。filterChain.dataSource_connect()參數中有this,說明它把自己傳進去了,
    說明這個filterChain並不從屬於任何datasource,可以是這個數據源,也可以是那個數據源。具體過濾哪個,臨時傳入。

    
3減少連接

    在創建連接線程附近還有一個DestroyConnectionThread()
    跟蹤里面,有destroyTask.run();----->shrink(true);連接空閑的太多了就縮小。

    在shrink()方法中,重點有下面的語句:

1 final int checkCount = poolingCount - minIdle;//池中的數量-最小空閑數量
2     
3 for (DruidConnectionHolder item : evictList) {//可回收的DruidConnectionHolder
4     Connection connection = item.getConnection();
5     JdbcUtils.close(connection);
6     destroyCount.incrementAndGet();
7 }


4init()

    創建線程與收縮線程都是由void init()來調用的,主要代碼如下。
   

 1 connections = new DruidConnectionHolder[maxActive];//新建連接池,個數是最大活動連接數maxActive。
 2 
 3 for (int i = 0, size = getInitialSize(); i < size; ++i) {//放入連接池中連接
 4     PhysicalConnectionInfo pyConnectInfo = createPhysicalConnection();
 5     DruidConnectionHolder holder = new DruidConnectionHolder(this, pyConnectInfo);
 6     connections[poolingCount] = holder;
 7     incrementPoolingCount();
 8 }
 9 
10 createAndLogThread();
11 createAndStartCreatorThread();//創建連接的線程,一直在工作,池子滿了就是等待狀態。
12 createAndStartDestroyThread();//收縮池子的線程,一直在工作。
13 
14 
15 initedLatch.await();//主線程在計數器為0前一直等待。
16 
17 init = true;


    這里有一個知識點。

1 CountDownLatch initedLatch = new CountDownLatch(2); 

        就叫倒計時同步器。當前同步數為2,在變成0后,主線程才能運行,否則一直等待中。
        在創建連接與收縮池子的線程中都有initedLatch.countDown();,
        一共正好兩個,主線程就是等待上面兩個線程都運行了才運行,才置init狀態標識為true。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM