简单的数据库连接池实例(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事务,什么是事务,事务是包含一组操作,这组操作里面包含许 ...
随机推荐
- 使用canvas实现画中画效果的H5
最近看到一个挺有趣的H5,主要效果就是通过不断的放缩来展示画中画,网上找了一下并没有这方面的实现代码,故决定原创一下,并分享出来 主要的思路就是通过canvas不断的写入图片,考虑到每一层的图片的位置 ...
- dedicated bearer
Session Initiation Protocol (SIP) Basic Call Flow ExamplesRFC3665 intuitive, done. PDF] TS 123 401 ...
- 基于vue-cli li列表的显示隐藏
效果:点击“公告标题”,显示公告内容,点击同一个“公告标题”多次,显示与隐藏切换 方法一: html部分代码: <ul class="clist"> <li v- ...
- C: City----逆向并查集
C: City 时间限制: 1 s 内存限制: 128 MB 题目描述 如果城市A和城市B互通,城市B和城市C互通,那么城市A和城市C也互通,A.B.C三个城市算一个聚集点.先 ...
- 【实战分享】安卓app测试的一些记录
一.app代码未混淆1.使用7zip解压apk文件2.执行命令:dex2jar.bat apk解压后文件夹中的classes.dex文件3.上述命令执行后会在apk文件夹中生成java源码文件clas ...
- Apache 配置代理服务
1.根据项目需要,Apache服务下面有2个tomcat 分别指向不同的域名 2.修改 Apache-conf-httpd.conf LoadModule proxy_module modules/m ...
- Linux-文件目录类命令
l 文件目录类 pwd 指令 基本语法 pwd (功能描述:显示当前工作目录的绝对路径) 应用实例 案例:显示当前工作目录的绝对路径 ls指令 基本语法 ls [选项] [目录或是文件] 常用选项 - ...
- 利用partial关键字声明分部类和分部方法
一.分部类 1.分部类的定义:简单的说,分部类就是把一个类拆分成多个类,每个类文件只包含其中的一部分,类.结构.接口.方法都可以拆分,在定义的时候加上partial修饰符. 注意:分部类必须属于同一命 ...
- 【随笔】 MyEclipse2014的安装和破解
MyEclipse,是在eclipse 基础上加上了自己的插件.MyEclipse,是在eclipse 基础上加上自己的插件开发而成的功能强大的企业级集成开发环境,主要用于Java.Java EE以及 ...
- Android Gson解析复杂Json
JSON原数据 {"total":1,"rows":[{"ID":1,"Title":"台州初级中学招收初一年 ...