简单的数据库连接池实例(java语言)
2017-05-21 13:15
471 查看
1.概述
频繁的创建和销毁数据库连接消耗非常多的系统资源,创建一个池子, 管理一定数量的连接,用的时候去池中取,用完了放回池中,这时比较通用的做法。
2.关键字
LinkedList synchronized InvocationHandler CountDownLatch
3. 代码
3.1 ConnectionPool.java
3.2 ConnectionDriver.java
3.3 ConnectionPoolTest.java
3.4 说明
通过改变main方法中的threadCount的数量可以观察 随着线程数的增加 获取连接命中的比例在下降,
这时因为连接池中的连接数一定(10个) 而客户端线程会等待并超时返回。
频繁的创建和销毁数据库连接消耗非常多的系统资源,创建一个池子, 管理一定数量的连接,用的时候去池中取,用完了放回池中,这时比较通用的做法。
2.关键字
LinkedList synchronized InvocationHandler CountDownLatch
3. 代码
3.1 ConnectionPool.java
package com.rocky.pool; import java.sql.Connection; import java.util.LinkedList; public class ConnectionPool { private LinkedList<Connection> pool = new LinkedList<Connection>(); public ConnectionPool(int initialSize){ if(initialSize > 0){ for(int i=0; i<initialSize; i++){ pool.addLast(ConnectionDriver.createConection()); } } } public void releaseConnection(Connection connection){ if(connection != null){ synchronized (pool) { //连接释放后 要进行通知 这样其他消费者能够感知池中已经归还了一个连接 pool.addLast(connection); // pool.notifyAll();//all pool.notify();//all } } } public Connection fetchConnection(long mills) throws InterruptedException{ synchronized (pool) { //超时 if(mills <= 0){ while(pool.isEmpty()){ pool.wait(); } return pool.removeFirst(); }else{ long future = System.currentTimeMillis() + mills; long remaining = mills; while(pool.isEmpty() && remaining >0){ pool.wait(remaining); remaining = future - System.currentTimeMillis(); } Connection result = null; if(!pool.isEmpty()){ result = pool.removeFirst(); } return result; } } } }
3.2 ConnectionDriver.java
package com.rocky.pool; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; public class ConnectionDriver { static class ConnectionHandler implements InvocationHandler{ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equals("commit")){ Thread.sleep(1000); } return null; } } //创建一个connection的代理 public static Connection createConection(){ return (Connection) Proxy.newProxyInstance(ConnectionDriver.class.getClassLoader(), new Class<?>[]{Connection.class},new ConnectionHandler()); } }
3.3 ConnectionPoolTest.java
package com.rocky.pool; import java.sql.Connection; import java.sql.SQLException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; public class ConnectionPoolTest { static ConnectionPool pool = new ConnectionPool(10); //保证所有runner能够同时运行 static CountDownLatch start = new CountDownLatch(1); static CountDownLatch end ; public static void main(String[] args) throws Exception { int threadCount = 20; end = new CountDownLatch(threadCount); int count = 20; AtomicInteger got = new AtomicInteger(); AtomicInteger notGot = new AtomicInteger(); for(int i=0; i<threadCount; i++){ Thread thread = new Thread(new ConnectionRunner(count, got, notGot), "ConectionRunnerThread"+i); thread.start(); } start.countDown(); end.await(); System.out.println("total invoke: "+ (threadCount) * count); System.out.println("got connection: "+got); System.out.println("not got connection "+ notGot); } static class ConnectionRunner implements Runnable{ int count ; AtomicInteger got; AtomicInteger notGot; public ConnectionRunner(int count, AtomicInteger got, AtomicInteger notGot){ this.count = count; this.got = got; this.notGot = notGot; } @Override public void run() { try { start.await(); } catch (InterruptedException e) { e.printStackTrace(); } while(count > 0){ try { Connection connection = pool.fetchConnection(1000); if(connection != null){ try{ connection.createStatement(); connection.commit(); }finally{ pool.releaseConnection(connection); got.incrementAndGet(); } }else{ notGot.incrementAndGet(); } } catch (InterruptedException | SQLException e) { e.printStackTrace(); }finally{ count--; } } end.countDown(); } } }
3.4 说明
通过改变main方法中的threadCount的数量可以观察 随着线程数的增加 获取连接命中的比例在下降,
这时因为连接池中的连接数一定(10个) 而客户端线程会等待并超时返回。
相关文章推荐
- JAVA简单实例-数据库设计思路引导(3)
- java语言搭建SSL的Socket并发送字符串消息(最简单应用实例/常见异常及解决)
- JAVA简单实例-数据库设计思路引导(4)
- Java中使用JDBC操作数据库简单实例
- Java 的动态代理实例(JDBC的数据库的连接池(DataSource))
- JAVA简单实例-数据库设计思路引导(1)
- 用Java实现简单的数据库连接池
- java使用jdbc连接数据库简单实例
- 数据库技术_Orcale技术(0002)_5分钟会用存储过程_存储过程简单实例(包含循环、条件、增改查、参数传入、变量赋值、java调用等)
- java JDBC:一个数据库的简单使用实例
- JAVA简单实例-数据库设计思路引导(2)
- 一个简单的数据库连接池实例
- Java1.5语言新特性简单总结
- 编译原理课程设计---用java写的SNLCompiler(简单嵌套语言SNL的编译程序)
- [软件发布]:简单数据库查询工具 v1.0 For MsSQL(Java版本)
- 功能完善的Java连接池调用实例
- .net页面间的参数传递简单实例 选择自 JavaProgramers 的 Blog
- Java基础的一些简单实例
- java连接postgreSQL数据库简单使用
- 使用Tomcat 连接池 连接数据库的实例