📄 poolmanager.java
字号:
/**
*
*/
package com.xuntian.material.data.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.Hashtable;
import com.xuntian.material.data.idao.ConnectPool;
import com.xuntian.material.exception.ConnectPoolException;
import com.xuntian.material.util.Constants;
import com.xuntian.material.util.DBConfig;
import com.xuntian.material.util.LogUtil;
/**
* @author zym
*/
public class PoolManager implements ConnectPool {
/**
* driver name
*/
private String driver = null;
/**
* db username
*/
private String userName = null;
/**
* db password
*/
private String password = null;
/**
* the driver URL
*/
private String url = null;
/**
* test table name
*/
private String testTable = null;
/**
* 最大连接数
*/
private int maxSize = 0;
/**
* 最小连接数
*/
private int minSize = 0;
/**
* 所有unlock连接失效时间,失效后重新建立
*/
private long expirationTime = 0L;
/**
* 初始化连接个数
*/
private int initSize = 0;
/**
* singleton建立poolManager
*/
private static PoolManager poolManager = new PoolManager();
/*
* 链接存放容器
*/
private Hashtable<Connection, Long> locked = null;
private Hashtable<Connection, Long> unlocked = null;
/**
*
*/
private PoolManager() {
driver = DBConfig.DRIVER;
url = DBConfig.URL;
maxSize = DBConfig.MAX_SIZE;
minSize = DBConfig.MIN_SIZE;
expirationTime = DBConfig.EXPIRATION_TIME;
initSize = DBConfig.INIT_SIZE;
userName = DBConfig.USERNAME;
password = DBConfig.PASSWORD;
testTable = DBConfig.TEST_TABLE;
//System.out.println(driver+url+userName+password);
init();
}
/**
* @return PoolManager
*/
public static PoolManager getInstance() {
return poolManager;
}
/**
* 初始化数据库连接, 同时启动对未使用连接的监控, 如果超时则使其失效
*/
private synchronized void init() {
try {
if (initSize <= 0) {
throw new ConnectPoolException("the initSize is wrong: "
+ initSize);
}
unlocked = new Hashtable<Connection, Long>(initSize);
locked = new Hashtable<Connection, Long>(initSize);
for (int i = 0; i < initSize; i++) {
Connection conn = create();
LogUtil.getLogger(this).info(conn);
unlocked.put(conn, new Long(System.currentTimeMillis()));
}
new AdjustPoolTools().start();
} catch (ConnectPoolException e) {
e.printStackTrace();
}
notifyAll();
}
/*
* (non-Javadoc)
*
* @see com.xuntian.data.dao.ConnectPool#checkIn(java.sql.Connection)
*/
public synchronized void checkIn(Connection con)
throws ConnectPoolException {
if (con != null) {
unlocked.put(con, locked.get(con));
locked.remove(con);
} else {
LogUtil.getLogger(this).error("null checkIn connection");
throw new ConnectPoolException("the checkIn connection is null!");
}
notifyAll();
}
/*
* (non-Javadoc)
*
* @see com.xuntian.data.dao.ConnectPool#checkOut()
*/
public synchronized Connection checkOut() throws ConnectPoolException {
Long now = System.currentTimeMillis();
Connection conn = null;
synchronized(unlocked){
if (unlocked.size() > 0) {
int getTimes=0;
for (Enumeration<Connection> enu = unlocked.keys();enu.hasMoreElements();){
int random=(int)(Math.random()*minSize);
if(random!=0){
random--;
getTimes+=1;
if(getTimes<=(minSize/2)){
conn = enu.nextElement();
continue;
}
}
conn = enu.nextElement();
if (validate(conn)) {
locked.put(conn, unlocked.get(conn));
unlocked.remove(conn);
long cnow = System.currentTimeMillis();
if (cnow - now > Constants.DB_KEY_TIMEOUT) {
notifyAll();
throw new ConnectPoolException(
"get connection form the unlocked time out!");
}
notifyAll();
return conn;
} else {
this.expire(conn);
unlocked.remove(conn);
boolean isOk = false;
while (!isOk) {
conn = create();
isOk = validate(conn);
if (isOk) {
locked.put(conn, new Long(System
.currentTimeMillis()));
notifyAll();
return conn;
}
}
}
}
} else if (unlocked.size() == 0 && locked.size() < maxSize) {
boolean createOk = false;
while (!createOk) {
conn = this.create();
if (validate(conn)) {
createOk = true;
locked.put(conn, new Long(System.currentTimeMillis()));
if (locked.get(conn).longValue() - now > Constants.DB_KEY_TIMEOUT) {
notifyAll();
throw new ConnectPoolException(
"create connection time out!");
}
notifyAll();
return conn;
}
}
}
}
notifyAll();
return conn;
}
/*
* (non-Javadoc)
*
* @see com.xuntian.data.dao.ConnectPool#monitorPool()
*/
public void monitorPool() {
String message = "the used connection amount is :" + locked.size()
+ "the NOT used connection amount is" + unlocked.size();
LogUtil.getLogger(PoolManager.class).info(message);
}
/*
* (non-Javadoc)
*
* @see com.xuntian.data.dao.ConnectPool#create()
*/
public Connection create() throws ConnectPoolException {
Connection conn = null;
if (unlocked.size() == 0 || (unlocked.size() + locked.size()) < maxSize) {
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, userName, password);
} catch (ClassNotFoundException e) {
String errorMessage = "Database driver can not find!";
LogUtil.getLogger(this).error(errorMessage);
throw new ConnectPoolException(errorMessage, e);
} catch (SQLException e) {
String errorMessage = "The config of database connection is wrong!";
LogUtil.getLogger(this).error(errorMessage);
throw new ConnectPoolException(errorMessage, e);
}
}
return conn;
}
/*
* (non-Javadoc)
*
* @see com.xuntian.data.dao.ConnectPool#validate(java.sql.Connection)
*/
public boolean validate(Connection con) throws ConnectPoolException {
boolean isOk = false;
if(con!=null){
try {
String sql = "select 1 from "+testTable;
Statement st = con.createStatement();
isOk = st.execute(sql);
} catch (SQLException e) {
LogUtil.getLogger(this).error("the connection now using is bad");
}
}
return isOk;
}
/*
* (non-Javadoc)
*
* @see com.xuntian.data.dao.ConnectPool#expire(java.sql.Connection)
*/
public void expire(Connection con) throws ConnectPoolException {
try {
con.close();
} catch (SQLException e) {
LogUtil.getLogger(this).error("Close connection error!");
throw new ConnectPoolException("Close connection error!", e);
}
}
public synchronized void clearConn(Connection con) throws ConnectPoolException{
expire(con);
unlocked.remove(con);
notifyAll();
}
/**
* @author lip Mar 7, 2006 copyright@xuntian 启动监视线程
*/
class AdjustPoolTools extends Thread {
public void run() {
try {
while (true) {
sleep(expirationTime);
// sleep(60000L);
monitorPool();
Hashtable<Connection, Long> newConn = new Hashtable<Connection, Long>(
);
for (int i = 0; i < minSize; i++) {
Connection con = create();
if (!validate(con)) {
i--;
continue;
}
newConn.put(con, new Long(System.currentTimeMillis()));
}
Enumeration<Connection> enu = unlocked.keys();
while (enu.hasMoreElements()) {
Connection conn = enu.nextElement();
if (checkTime(unlocked.get(conn).longValue())) {
clearConn(conn);
LogUtil.getLogger(this).info("连接被关掉!");
}
}
unlocked.putAll(newConn);
monitorPool();
// sort(unlocked);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ConnectPoolException e) {
e.printStackTrace();
}
}
/**
* @param createTime
* @return true:time out false:NOT timeout
*/
private boolean checkTime(long createTime) {
long now = System.currentTimeMillis();
if (now - createTime > expirationTime) {
return true;
}
return false;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -