根据数据库连接池的原理,自己编写了一个小程序来实现数据库连接池中的简单功能。当连接资源不够用是能够实现连接的自动创建,当空闲连接过多时,能够实现空闲连接的自动回收和关闭。(本程序的连接池连接管理算法并没有优化,希望各位大神能测试优化);
连接池实现代码
DBConnectionPool.java
package hl.douban.dbConnection;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.util.Queue;
import java.util.Vector;
public class DBConnectionPool {
private static int rnum= 0;
private static DBConnectionPool instance= null;
private Vector<Connection> activePool = new Vector<Connection>();
private Vector<Connection> usedPool = new Vector<Connection>();
private String driverClassName;
private String username;
private String password;
private String url;
private static boolean flag = false;
//制定连接池中的最小连接数
private int minPoolsize = 20;
//制定连接池中的可用连接数超过制定范围,最大自动减少时间;
private int maxReduceIdleTime = 10;
//指定当连接池可用连接数等于总连接数时,最大关闭连接池的时间。 -1 表示永不关闭
private int maxExitIdleTime = -1;
public String getDriverClassName() {
return driverClassName;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getUrl() {
return url;
}
public int getMinPoolsize() {
return minPoolsize;
}
public int getMaxReduceIdleTime() {
return maxReduceIdleTime;
}
public int getMaxExitIdleTime() {
return maxExitIdleTime;
}
/**
* 私有构造方法,不允许外界创建构造方法
*
*/
private DBConnectionPool(){
createConnection();
}
/**
* 初始化数据库连接池,读取配置文件,创建数据库连接
*
*/
public void init(){
createConnection();
}
public static void startThread(){
//创建此线程用户,用于当连接池中的连接资源小于一定范围是,自动向连接池中创建新的连接对象
MonitorThread mt = new MonitorThread();
Thread t2 = new Thread(mt);
t2.setDaemon(false);
t2.start();
//创建此线程用于当连接吃中的闲置连接大于一定范围并且超出特定时间范围时,自动减少连接池中的连接对象并关闭
MonitorThread2 mt2 = new MonitorThread2(mt);
Thread t3 = new Thread(mt2);
t3.setDaemon(false);
t3.start();
}
/**
* 返回连接池中可用连接的数量
*
* @return
*/
public int getActicePoolSize(){
return activePool.size();
}
/**
*
*
* @return 返回连接池中被占用的连接数
*/
public int getUsedPoolSize(){
return usedPool.size();
}
/**
*
* 返回当前连接池的一个对象
*
* @return
*/
public static DBConnectionPool getInstance(){
if (instance == null) {
instance = new DBConnectionPool();
if(!flag){
startThread();
flag = true;
}
}
return instance;
}
/**
*
* 释放连接资源到连接池中
*
* @param conn 被释放的连接
*
*/
public synchronized void Release(Connection conn){
usedPool.remove(conn);
activePool.add(conn);
}
/**
*
* 从连接池中获取一个连接对象
*
* @return 返回一个数据库连接对象Connetion
*/
public synchronized Connection getConnection(){
if(activePool.size()>0){
Connection conn = activePool.remove(0);
usedPool.add(conn);
return conn;
}
return null;
}
/**
*
* 向连接池中添加新的连接
*
* @param newPool
*/
public synchronized void addConnection(Vector<Connection> newPool){
activePool.addAll(newPool);
}
/**
* 初始化连接池,向连接池中添加连接
*
*/
public void createConnection(){
Connection conn =null;
readConfig();
// instance = new DBConnectionPool();
for(int i=0; i < minPoolsize ; i++){
try {
Class.forName(driverClassName);
conn = DriverManager.getConnection(url, username, password);
System.out.println("数据连接"+conn);
activePool.add(conn);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public synchronized void reduceConnection(int n){
Connection conn = null;
int i = 0;
System.out.println("**************第"+(++rnum)+"次*************减少连接**********");
while(i<n){
conn = activePool.remove(activePool.size()-1);
try {
conn.close();
System.out.println(conn+"已经关闭");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
i++;
}
}
/**
*
* 关闭所有连接池中的数据库连接
*
*
*/
public synchronized void closeConnection(){
System.out.println("------------正在关闭连接");
for(int i=0; i<activePool.size(); i++){
try {
activePool.get(i).close();
System.out.println(activePool.get(i)+"----------已经关闭");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("关闭数据库连接时出错");
}
}
activePool.removeAllElements();
for(int i=0; i<usedPool.size(); i++){
try {
usedPool.get(i).close();
System.out.println(usedPool.get(i)+"----------已经关闭");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("关闭数据库连接时出错");
}
}
usedPool.removeAllElements();
System.out.println("------------连接已经全部关闭");
}
/**
*
* 读取配置文件
*/
private void readConfig(){
File configFile = new File("dbPoolConfig.properties");
if(configFile.exists()){
BufferedReader br;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(configFile)));
Properties properties = new Properties();
properties.load(br);
driverClassName = properties.getProperty("driverClassName");
username = properties.getProperty("username");
password = properties.getProperty("password");
int initPoolsize = Integer.parseInt(properties.getProperty("poolsize"));
minPoolsize = initPoolsize>minPoolsize?initPoolsize:minPoolsize;
url = properties.getProperty("url");
maxExitIdleTime = Integer.parseInt(properties.getProperty("maxExitIdleTime"));
maxReduceIdleTime =Integer.parseInt(properties.getProperty("maxReduceIdleTime"));
System.out.println(maxExitIdleTime +"---"+maxReduceIdleTime+"---"+password+"----"+minPoolsize+"----"+url);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("读取配置文件出错!!!");
}
}else{
System.out.println("配置文件不存在!!!");
try {
configFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class MonitorThread implements Runnable {
private int num = 0;
private int usedPoolSize ;
private int activePoolSize ;
private int countSize;
private boolean flag = true;
DBConnectionPool dbpool = null;
public void endThread(){
flag = false;
}
@Override
public void run() {
dbpool = DBConnectionPool.getInstance();
while(dbpool !=null && flag){
activePoolSize = dbpool.getActicePoolSize();
usedPoolSize = dbpool.getUsedPoolSize();
countSize = activePoolSize + usedPoolSize;
// System.out.println("activePoolSize数量为:------"+activePoolSize);
// System.out.println("usedPoolSize数量为:------"+usedPoolSize);
// System.out.println("countSize数量为:------"+countSize);
if(activePoolSize==(countSize/4)){
dbpool.addConnection(createConnection(activePoolSize*2));
}
}
}
private synchronized Vector<Connection> createConnection(int size){
Vector<Connection> newpool = new Vector<Connection>();
Connection conn =null;
System.out.println("=========================第"+(++num)+"次 ==============扩大连接=================");
for(int i=0; i < size ; i++){
try {
Class.forName(dbpool.getDriverClassName());
conn = DriverManager.getConnection(dbpool.getUrl(),dbpool.getUsername(), dbpool.getPassword());
System.out.println("数据连接"+conn);
newpool.add(conn);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return newpool;
}
}
class MonitorThread2 implements Runnable{
private int usedPoolSize ;
private int activePoolSize ;
private int countSize;
private Vector<Connection> pool;
private boolean flag = true;
MonitorThread t = null;
public MonitorThread2(MonitorThread t) {
// TODO Auto-generated constructor stub
this.t = t;
}
private int reduceIdletime =0;
private int exitIdleTime = 0;
public void endThread(){
flag = false;
}
@Override
public void run() {
DBConnectionPool dbpool = DBConnectionPool.getInstance();
// TODO Auto-generated method stub
while(dbpool !=null && flag){
activePoolSize = dbpool.getActicePoolSize();
usedPoolSize = dbpool.getUsedPoolSize();
countSize = activePoolSize + usedPoolSize;
try {
Thread.sleep(1000);
System.out.println("------------------------闲置时间为:"+ reduceIdletime +"-------------------------");
System.out.println("activePoolSize数量为:------"+activePoolSize);
System.out.println("usedPoolSize数量为:------"+usedPoolSize);
System.out.println("countSize数量为:------"+countSize);
/**
*
* 当超过连接池中的可用连接数过大并超过 制定的 reduceIdletime 时间时,
* 自动减少并关闭连接池中的一定数目的连接
*
*/
if((activePoolSize>=(countSize*3)/4)&&countSize>dbpool.getMinPoolsize()){
reduceIdletime++;
if(reduceIdletime==dbpool.getMaxReduceIdleTime()&&(countSize-activePoolSize/4)>=dbpool.getMinPoolsize()){
dbpool.reduceConnection(activePoolSize/4);
reduceIdletime =0;
}
}else{
reduceIdletime =0;
}
/**
*
* 当连接池在 idleTime 时间内 都没人使用就自动关闭连接池
*
* idleTime = -1 时表示,永不关闭
*
*
*/
if(usedPoolSize == 0){
exitIdleTime++;
if(exitIdleTime == dbpool.getMaxExitIdleTime() ){
t.endThread();
dbpool.closeConnection();
endThread();
System.out.println("-----------程序全部退出------------");
}
}else{
exitIdleTime = 0;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
连接池配置文件
dbPoolConfig.properties
username=han
password=han
url=jdbc:oracle:thin:@localhost:1521:orcl
driverClassName=oracle.jdbc.driver.OracleDriver
poolsize=20
maxExitIdleTime=-1
maxReduceIdleTime=10
连接池测试程序
package hl.douban.dbConnection;
import java.sql.Connection;
import java.util.Vector;
public class test {
public static void main(String[] args) {
Vector<Connection> c = new Vector<Connection>();
DBConnectionPool dbpool = DBConnectionPool.getInstance();
try {
for(int i=0; i<30; i++){
Connection conn;
conn = dbpool.getConnection();
c.add(conn);
Thread.sleep(1000);
}
while(c.size()>0){
dbpool.Release(c.remove(0));
Thread.sleep(1000);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}