源碼來源於http://www.toutiao.com/a6350448676050174209/,留存以供之後參考學習java
先上一張項目託普圖mysql
而後分別列出各個文件的源碼:sql
MyPool.java(就是個接口)數據庫
package com.audi; public interface MyPool { PoolConnection getConnection(); void createConnections(int count); }
MyPoolImpl.java(接口的實現類)ide
package com.audi; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; import java.util.Vector; import com.mysql.jdbc.Driver; public class MyPoolImpl implements MyPool { private static String jdbcDriver = ""; private static String jdbcUrl = ""; private static String userName = ""; private static String password = ""; private static int initCount; private static int stepSize; private static int poolMaxSize; private static Vector<PoolConnection> poolConnections = new Vector<PoolConnection>(); public MyPoolImpl() { // TODO Auto-generated constructor stub init(); } private void init() { // TODO Auto-generated method stub // 讀取配置文件 InputStream in = MyPoolImpl.class.getClassLoader() .getResourceAsStream("mysqlConnection.properties"); // InputStream inputStream = new in Properties pro = new Properties(); try { // 裝載配置文件輸入流 pro.load(in); } catch (Exception e) { // TODO: handle exception } // 從配置文件中讀取出配置參數 jdbcDriver = pro.getProperty("jdbcDriver"); jdbcUrl = pro.getProperty("jdbcUrl"); userName = pro.getProperty("userName"); password = pro.getProperty("password"); initCount = Integer.valueOf(pro.getProperty("initCount")); stepSize = Integer.valueOf(pro.getProperty("stepSize")); poolMaxSize = Integer.valueOf(pro.getProperty("poolMaxSize")); try { // 獲取驅動對象並註冊 Driver driver = (Driver) Class.forName(jdbcDriver).newInstance(); DriverManager.registerDriver(driver); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } // 建立必定數量的初始連接 createConnections(initCount); } @Override public PoolConnection getConnection() { // TODO Auto-generated method stub if (poolConnections.size() <= 0) { System.out.println("連接池爲空,獲取數據庫連接失敗!!!"); throw new RuntimeException("連接池爲空,獲取數據庫連接失敗!!!"); } PoolConnection connection = getRealConnection(); // 若是沒有成功的獲取連接就建立必定數量的連接 並從中獲取一個有效連接 while(connection == null) { createConnections(stepSize); connection = getRealConnection(); try { // 這裏睡眠的緣由時考慮到第一次獲取連接失敗,可能有多個線程在等待連接資源,因此當前線程先等待一下,避開高峯 Thread.sleep(300); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } return connection; } // 注意有synchronized關鍵字 private synchronized PoolConnection getRealConnection() { // TODO Auto-generated method stub for (PoolConnection conn : poolConnections) { // 若是當前連接空閒則返回該連接對象 if (!conn.isBusy()) { Connection connection = conn.getConn(); try { // 判斷得到的連接是不是有效的,若是無效就建立一個新的連接 isValid方法其實就是在定時時間到的時候執行一下sql語句 if (!connection.isValid(2000)) { Connection validConn = DriverManager.getConnection(jdbcUrl, userName, password); conn.setConn(validConn); } } catch (Exception e) { // TODO: handle exception } } conn.setBusy(true); return conn; } return null; } // 建立連接 @Override public void createConnections(int count) { // TODO Auto-generated method stub if (poolMaxSize > 0 && poolConnections.size() + count > poolMaxSize) { System.out.println("建立連接對象失敗,由於數據庫連接數量已達上限!!"); throw new RuntimeException("建立連接對象失敗,由於數據庫連接數量已達上限!!"); } // 不然就開始建立連接 for (int i = 0; i < count; i++) { try { Connection conn = DriverManager.getConnection(jdbcUrl, userName, password); // 封裝連接對象 並存入vecter PoolConnection poolConnection = new PoolConnection(conn, false); poolConnections.add(poolConnection); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
PoolConnection.java(裏面會進行一些鏈接參數的配置)學習
package com.audi; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; public class PoolConnection { private Connection conn; private boolean isBusy = false; public Connection getConn() { return conn; } public void setConn(Connection conn) { this.conn = conn; } public boolean isBusy() { return isBusy; } public void setBusy(boolean isBusy) { this.isBusy = isBusy; } public PoolConnection(Connection conn,boolean isBusy) { this.conn = conn; this.isBusy = isBusy; } public ResultSet querySql(String sql) { ResultSet resultSet = null; Statement statement = null; try { statement = conn.createStatement(); resultSet = statement.executeQuery(sql); } catch (Exception e) { // TODO: handle exception } return resultSet; } public void close() { this.isBusy = false; } }
PoolManager.java(使用內部類的方式獲取鏈接池對象)測試
package com.audi; public class PoolManager { private static class CreatePool { private static MyPoolImpl myPoolImpl= new MyPoolImpl(); } public static MyPoolImpl getInStance() { return CreatePool.myPoolImpl; } }
最後是測試類this
package com.audi; import java.sql.ResultSet; public class TestPool { private static MyPoolImpl poolImpl =PoolManager.getInStance(); public static void main(String[] args) { // TODO Auto-generated method stub /*long time= System.currentTimeMillis(); for (int i = 0; i < 2000; i++) { System.out.println("第"+i+"次執行"); selecData(); } System.out.println("運行時間"+(System.currentTimeMillis()-time));*/ // System.out.println(new Date()); //selecData(); // 建立2000個數據庫連接線程 long time= System.currentTimeMillis(); for (int i = 0; i < 2000; i++) { System.out.println("第"+i+"次執行"); new Thread(new Runnable() { public void run() { selecData(); } }); } System.out.println("運行時間"+(System.currentTimeMillis()-time)); } public synchronized static void selecData() { PoolConnection connection = poolImpl.getConnection(); ResultSet resultSet = connection.querySql("select * from Student"); try { while (resultSet.next()) { System.out.println(resultSet.getString("ID")+"\t"+resultSet.getString("NAME")+"\t"+resultSet.getString("AGE")); } resultSet.close(); connection.close(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }
數據庫鏈接參數配置文件線程
mysqlConnection.properties對象
jdbcDriver=com.mysql.jdbc.Driver jdbcUrl=jdbc\:mysql\://localhost\:3306/test userName=root password=w513723 initCount=10 stepSize=5 poolMaxSize=200