JAVA學習日記-自定義數(shù)據(jù)庫連接池類

當有多個線程,每個線程都需要連接數(shù)據(jù)庫執(zhí)行SQL語句的話,那么每個線程都會創(chuàng)建一個連接,并且在使用完畢后,關(guān)閉連接。

創(chuàng)建連接和關(guān)閉連接的過程也是比較消耗時間的,當多線程并發(fā)的時候,系統(tǒng)就會變得很卡頓。

同時,一個數(shù)據(jù)庫同時支持的連接總數(shù)也是有限的,如果多線程并發(fā)量很大,那么數(shù)據(jù)庫連接的總數(shù)就會被消耗光,后續(xù)線程發(fā)起的數(shù)據(jù)庫連接就會失敗。

原理

與傳統(tǒng)方式不同,連接池在使用之前,就會創(chuàng)建好一定數(shù)量的連接。
如果有任何線程需要使用連接,那么就從連接池里面借用,而不是自己重新創(chuàng)建.
使用完畢后,又把這個連接歸還給連接池供下一次或者其他線程使用。
倘若發(fā)生多線程并發(fā)情況,連接池里的連接被借用光了,那么其他線程就會臨時等待,直到有連接被歸還回來,再繼續(xù)使用。
整個過程,這些連接都不會被關(guān)閉,而是不斷的被循環(huán)使用,從而節(jié)約了啟動和關(guān)閉連接的時間。

package jdbc;
  
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
  
public class ConnectionPool {
  
    List<Connection> cs = new ArrayList<Connection>();
  
    int size;
  
    public ConnectionPool(int size) {
        this.size = size;
        init();
    }
  
    public void init() {
          
        //這里恰恰不能使用try-with-resource的方式,因為這些連接都需要是"活"的,不要被自動關(guān)閉了
        try {
            Class.forName("com.mysql.jdbc.Driver");
            for (int i = 0; i < size; i++) {
                Connection c = DriverManager
                        .getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8", "root", "admin");
  
                cs.add(c);
  
            }
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
  
    public synchronized Connection getConnection() {
        while (cs.isEmpty()) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        Connection c = cs.remove(0);
        return c;
    }
  
    public synchronized void returnConnection(Connection c) {
        cs.add(c);
        this.notifyAll();
    }
  
}

測試

package jdbc;
  
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
 
import jdbc.ConnectionPool;
   
public class TestConnectionPool {
   
    public static void main(String[] args) {
        ConnectionPool cp = new ConnectionPool(3);
        for (int i = 0; i < 100; i++) {
            new WorkingThread("working thread" + i, cp).start();
        }
   
    }
}
   
class WorkingThread extends Thread {
    private ConnectionPool cp;
   
    public WorkingThread(String name, ConnectionPool cp) {
        super(name);
        this.cp = cp;
    }
   
    public void run() {
        Connection c = cp.getConnection();
        System.out.println(this.getName()+ ":\t 獲取了一根連接,并開始工作"  );
        try (Statement st = c.createStatement()){
             
            //模擬時耗1秒的數(shù)據(jù)庫SQL語句
            Thread.sleep(1000);
            st.execute("select * from hero");
   
        } catch (SQLException | InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        cp.returnConnection(c);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容