源码来源于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