简单的数据库连接池实例(java语言)
1.概述
频繁的创建和销毁数据库连接消耗非常多的系统资源,创建一个池子, 管理一定数量的连接,用的时候去池中取,用完了放回池中,这时比较通用的做法。
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语言)的更多相关文章
- 数据源与JNDI资源实现JSP数据库连接池实例
名词解释:JNDI的全称是java命名与目录接口(Java Naming and Directory Interface),是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通 ...
- [数据库连接池二]Java数据库连接池--C3P0和JDNI.
前言:上一篇文章中讲了DBCP的用法以及实现原理, 这一篇再来说下C3P0和JDNI的用法. 1.1.C3P0数据源 C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规 ...
- mongodb数据库连接池(java版)
mongodb数据库接口的设计 package storm.db; import java.util.ArrayList; import com.mongodb.DB; import com.mong ...
- 简单理解数据库连接池(JDBC)
为什么要使用连接池? 在我们写代码的时候,写了很多类,假如这些类都和数据库打交道.这样的话每个类都要去获取数据库连接,操作完了之后就把连接释放了. 要知道,获取数据库连接的操作其实是向操作系统底层去获 ...
- Python数据库连接池实例——PooledDB
不用连接池的MySQL连接方法 import MySQLdbconn= MySQLdb.connect(host='localhost',user='root',passwd='pwd',db='my ...
- Python数据库连接池实例——PooledDB
不用连接池的MySQL连接方法 import MySQLdb conn= MySQLdb.connect(host='localhost',user='root',passwd='pwd',db='m ...
- dbcp数据库连接池的java实现
1.准备 导入jar包 commons-dbcp-1.4.jar commons-pool-1.3.jar 数据库驱动包,如:mysql-connector-java-5.1.28-bin.jar 2 ...
- C3P0数据库连接池的java实现
1.配置准备 导入jar包 c3p0-0.9.2-pre1.jar mchange-commons-0.2.jar 数据库驱动包,如:mysql-connector-java-5.1.28-bin.j ...
- 第77节:Java中的事务和数据库连接池和DBUtiles
第77节:Java中的事务和数据库连接池和DBUtiles 前言 看哭你,字数:8803,承蒙关照,谢谢朋友点赞! 事务 Transaction事务,什么是事务,事务是包含一组操作,这组操作里面包含许 ...
随机推荐
- MINIUI监听处理"drawcell"事件
http://www.blogjava.net/grid/archive/2012/11/02/390693.html jQuery MiniUI 开发教程 表格控件 表格:自定义单元格(三) ...
- JavaWeb学习笔记(二十一)—— 监听器Listener
一.监听器概述 JavaWeb中的监听器是Servlet规范中定义的一种特殊类,它用于监听web应用程序中的ServletContext, HttpSession和 ServletRequest等域对 ...
- PHP错误与异常处理
https://www.cnblogs.com/zyf-zhaoyafei/p/6928149.html 请一定要注意,没有特殊说明:本例 PHP Version < 7 说起PHP异常处理,大 ...
- oracle 行列转换函数之WM_CONCAT和LISTAGG的使用(一)
一.wm_concat函数 wm_concat能够实现同样的功能,但是有时在11g中使用需要用to_char()进行转换,否则会出现不兼容现象(WMSYS.WM_CONCAT: 依赖WMSYS 用户, ...
- ajax乱码的问题
ajax 乱码情况与原因很多,本文只讲其中之一: 浏览器端正常的数据,用ajax提交到服务器上就乱码了. 当ajax的提交方式是get而不是post时,其所携带的数据不会被字符编码过滤器所拦截(事实上 ...
- leetcode有意思的题目总结
231. 2的幂 2^3=8 得 8是2的幂 判断一个整数是不是2的幂,可根据二进制来分析.2的幂如2,4,8,等有一个特点: 二进制数首位为1,其他位为0,如2为10,4为100 2&(2 ...
- sql server取某个时间段内所有日期或者所有月份
取所有月份: declare @begin datetime,@end datetime set @begin='2015-2-6' set @end='2015-12-2' declare @mon ...
- SQL Server触发器创建、删除、修改、查看
一:触发器是一种特殊的存储过程,它不能被显式地调用,而是在往表中插入记录﹑更新记录或者删除记录时被自动地激活.所以触发器可以用来实现对表实施复杂的完整性约束. 二:SQL Server为每个触发器都创 ...
- db2 monitor event
1.创建事件监控器至少需要哪些权限? DBADM authority SQLADM authority 2.事件监控器的种类有哪些? 3. db2 flush event monitor eventm ...
- PHP面向对象的基本原则
对象内部是高内聚的 ——对象只负责一项特定的功能(职能可大可小) ——所有对象相关的内容都封装到对象内部 高内聚就是该有的都有,用的时候不会缺胳膊少腿! 对象对外是低耦合的 ——外部世界可以看到对象的 ...