import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* 基本功能描述:
* 数据库连接池类 DatabaseConnectionPool.提供如下的方法:
* 1.从池中取得一个打开的连接;
* 2.将一个连接返回池中;
* 3.在关闭时释放所有的资源,并关闭所有的连接.
* 4.DatabaseConnectionPool 还处理连接失败,比如超时,通讯失败等错误,并且根据预定义的参数限制池中的连接数.
*/
public class DatabaseConnectionPool extends Object {
private String URL = null; //数据库URL
private String user = null; //数据库登录名
private String password = null; //数据库登录名
private int capacityOfConnectionPool = 0; //数据库连接池最大连接数
private int activeConnectionsOfConnectionPool = 0; //已经建立数据库连接的连接数
private final int DEFAULT_CONNECTION_CAPACITY = 10;
private final int DEFAULT_ACTIVE_CONNECTION = 1;
private ObjectFIFOQueue idleGenericConnectionQueue = null; //空闲数据库连接队列
private Connection[] genericConnectionReferenceList = null; //所有已经建立连接的数据库连接引用列表,避免连接引用丢失(资源泄漏)
public DatabaseConnectionPool(String driverName,String URL,String user,String password,
int capacityOfConnectionPool,int activeConnectionsOfConnectionPool)
throws Exception
{
this.URL = URL;
this.user = user;
this.password = password;
this.capacityOfConnectionPool = capacityOfConnectionPool;
this.capacityOfConnectionPool = (this.capacityOfConnectionPool > 0)? this.capacityOfConnectionPool:DEFAULT_CONNECTION_CAPACITY;
activeConnectionsOfConnectionPool = (activeConnectionsOfConnectionPool > 0)? activeConnectionsOfConnectionPool:DEFAULT_ACTIVE_CONNECTION;
activeConnectionsOfConnectionPool = (this.capacityOfConnectionPool >= activeConnectionsOfConnectionPool)? activeConnectionsOfConnectionPool:this.capacityOfConnectionPool;
System.out.println("DatabaseConnectionPool : capacityOfConnectionPool = " + capacityOfConnectionPool);
System.out.println("DatabaseConnectionPool : activeConnectionsOfConnectionPool = " + activeConnectionsOfConnectionPool);
System.out.println("DatabaseConnectionPool : this.activeConnectionsOfConnectionPool = " + this.activeConnectionsOfConnectionPool);
if (!loadDriver(driverName))
{
throw new Exception("Loading DataBase's Driver Failed.");
}
idleGenericConnectionQueue = new ObjectFIFOQueue(capacityOfConnectionPool);
genericConnectionReferenceList = new Connection[capacityOfConnectionPool];
int lengthOfgenericConnectionReferenceList = genericConnectionReferenceList.length;
for (int index = 0; index < lengthOfgenericConnectionReferenceList; index++)
{
genericConnectionReferenceList[index] = null;
}
for (int index = 0; index < activeConnectionsOfConnectionPool; index++)
{
if (genericConnectionReferenceList[index] == null)
{
//genericConnectionReferenceList[index] = getConnection(URL,user,password);
genericConnectionReferenceList[index] = establishConnection(URL,user,password);
if (genericConnectionReferenceList[index] == null)
{
//this.activeConnectionsOfConnectionPool--; //bug
System.out.println("DatabaseConnectionPool : Initialize Active Connection Failed. Index = " + index);
}
else
{
this.activeConnectionsOfConnectionPool++;
idleGenericConnectionQueue.add(genericConnectionReferenceList[index]);
System.out.println("DatabaseConnectionPool : Initialize Active Connection OK. Index = " + index);
}
}
}
}
private boolean loadDriver(String driverName)
{
boolean flags = false;
try
{
Class.forName(driverName).newInstance();
System.out.println("loadDriver : Driver Loading...");
flags = true;
}
catch (InstantiationException ex)
{
ex.printStackTrace();
flags = false;
}
catch (IllegalAccessException ex)
{
ex.printStackTrace();
flags = false;
}
catch (ClassNotFoundException ex)
{
ex.printStackTrace();
flags = false;
}
catch (Exception ex)
{
ex.printStackTrace();
flags = false;
}
finally
{
}
return flags;
}
//建立新连接
private Connection establishConnection(String URL,String user,String password)
{
Connection genericConnection = null;
try
{
genericConnection = DriverManager.getConnection(URL, user, password);
System.out.println("establishConnection : Created a new Connection in DatabaseConnectionPool.");
}
catch (SQLException ex)
{
System.out.println("establishConnection : SQLException.");
ex.printStackTrace();
genericConnection = null;
}
catch (Exception ex)
{
System.out.println("establishConnection : Exception.");
ex.printStackTrace();
genericConnection = null;
}
finally
{
}
return genericConnection;
}
//从池中打开/得到一个连接
//public synchronized Connection getConnection(String URL,String user,String password)
public synchronized Connection getConnection()
throws Exception
{
Connection genericConnection = null;
System.out.println("getConnection : capacityOfConnectionPool = " + capacityOfConnectionPool);
System.out.println("DatabaseConnectionPool : this.activeConnectionsOfConnectionPool = " + this.activeConnectionsOfConnectionPool);
if (activeConnectionsOfConnectionPool < capacityOfConnectionPool)
{
if (idleGenericConnectionQueue.isQueueEmpty())
{
System.out.println("getConnection : idleGenericConnectionQueue isQueueEmpty.");
genericConnection = establishConnection(URL,user,password);
System.out.println("getConnection : establishConnection Returned.");
if (genericConnection != null)
{
activeConnectionsOfConnectionPool++;
int lengthOfgenericConnectionReferenceList = genericConnectionReferenceList.length;
for (int index = 0; index < lengthOfgenericConnectionReferenceList; index++)
{
if (genericConnectionReferenceList[index] == null)
{
System.out.println("getConnection : Creating Index = " + index);
genericConnectionReferenceList[index] = genericConnection;
break;
}
}
}
else
{
System.out.println("getConnection : establishConnection Returned Null.");
}
try
{
if (genericConnection != null)
{
if (genericConnection.isClosed())
{
System.out.println("getConnection : Creating -- genericConnection is Closed.");
}
}
}
catch (SQLException ex)
{
}
catch (Exception ex)
{
}
finally
{
}
System.out.println("getConnection : Returning New Connection.");
return genericConnection;
}
}
//得到的连接可能已经关闭
genericConnection = (Connection)idleGenericConnectionQueue.remove(); //block
try
{
if (genericConnection.isClosed())
{
System.out.println("getConnection : Getting -- genericConnection is Closed.");
}
}
catch (SQLException ex)
{
}
catch (Exception ex)
{
}
finally
{
}
System.out.println("getConnection : Returning Existing Connection.");
return genericConnection;
}
//回收连接池中已经关闭的连接/空引用的连接
public synchronized void collectInvalidateConnection()
{
int activeConnectionsOfConnectionPool = 0;
int lengthOfgenericConnectionReferenceList = genericConnectionReferenceList.length;
for (int index = 0; index < lengthOfgenericConnectionReferenceList; index++)
{
if (genericConnectionReferenceList[index] != null)
{
try
{
if (genericConnectionReferenceList[index].isClosed())
{
genericConnectionReferenceList[index] = null;
System.out.println("collectInvalidateConnection : Collecting... Index = " + index);
}
else
{
activeConnectionsOfConnectionPool++;
}
}
catch (SQLException ex)
{
System.out.println("collectInvalidationConnection : SQLException." );
ex.printStackTrace();
}
catch (Exception ex)
{
System.out.println("collectInvalidationConnection : Exception." );
ex.printStackTrace();
}
finally
{
}
}
}
this.activeConnectionsOfConnectionPool = activeConnectionsOfConnectionPool;
}
//将一个连接返回池中
public synchronized void freeConnection(Connection genericConnection)
throws Exception
{
idleGenericConnectionQueue.add(genericConnection);
System.out.println("freeConnection : Freeing Connection.");
}
//释放数据库连接池资源
public synchronized void releaseDatabaseConnectionPool()
throws Exception
{
//release genericConnectionReferenceList
int lengthOfgenericConnectionReferenceList = genericConnectionReferenceList.length;
for (int index = 0;index < lengthOfgenericConnectionReferenceList;index++)
{
try
{
if (genericConnectionReferenceList[index] != null)
{
if (!genericConnectionReferenceList[index].isClosed())
{
genericConnectionReferenceList[index].close();
genericConnectionReferenceList[index] = null;
System.out.println("releaseDatabaseConnectionPool : Index = " + index);
}
}
}
catch (SQLException ex)
{
System.out.println("releaseDatabaseConnectionPool : SQLException." );
ex.printStackTrace();
}
catch (Exception ex)
{
System.out.println("releaseDatabaseConnectionPool : Exception." );
ex.printStackTrace();
}
finally
{
}
}
if (genericConnectionReferenceList != null)
{
genericConnectionReferenceList = null;
}
//release idleGenericConnectionQueue
if (!idleGenericConnectionQueue.isQueueEmpty())
{
idleGenericConnectionQueue.removeAll();
}
if (idleGenericConnectionQueue != null)
{
idleGenericConnectionQueue = null;
}
}
}
下面的FIFO队列程序引自: Java Thread Programming (Sams)
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import java.util.Hashtable;
import java.util.Enumeration;
public class ObjectFIFOQueue extends Object {
private Object[] queue;
private int capacity;
private int size;
private int head;
private int tail;
public ObjectFIFOQueue(int cap) {
capacity = ( cap > 0 ) ? cap : 1; // at least 1
queue = new Object[capacity];
head = 0;
tail = 0;
size = 0;
}
public int getCapacity() {
return capacity;
}
public synchronized int getSize() {
return size;
}
public synchronized boolean isQueueEmpty() {
return ( size == 0 );
}
public synchronized boolean isFull() {
return ( size == capacity );
}
public synchronized void add(Object obj)
throws InterruptedException {
waitWhileFull();
queue[head] = obj;
head = ( head + 1 ) % capacity;
size++;
notifyAll(); // let any waiting threads know about change
}
public synchronized void addEach(Object[] list)
throws InterruptedException {
for ( int i = 0; i < list.length; i++ ) {
add(list[i]);
}
}
public synchronized Object remove()
throws InterruptedException {
waitWhileEmpty();
Object obj = queue[tail];
queue[tail] = null;
tail = ( tail + 1 ) % capacity;
size--;
notifyAll(); // let any waiting threads know about change
return obj;
}
public synchronized Object[] removeAll()
throws InterruptedException {
Object[] list = new Object[size]; // use the current size
for ( int i = 0; i < list.length; i++ ) {
list[i] = remove();
}
// if FIFO was empty, a zero-length array is returned
return list;
}
public synchronized Object[] removeAtLeastOne()
throws InterruptedException {
waitWhileEmpty(); // wait for at least one to be in FIFO
return removeAll();
}
public synchronized boolean waitUntilEmpty(long msTimeout)
throws InterruptedException {
if ( msTimeout == 0L ) {
waitUntilEmpty(); // use other method
return true;
}
// wait only for the specified amount of time
long endTime = System.currentTimeMillis() + msTimeout;
long msRemaining = msTimeout;
while ( !isQueueEmpty() && ( msRemaining > 0L ) ) {
wait(msRemaining);
msRemaining = endTime - System.currentTimeMillis();
}
// May have timed out, or may have met condition,
// calc return value.
return isQueueEmpty();
}
public synchronized void waitUntilEmpty()
throws InterruptedException {
while ( !isQueueEmpty() ) {
wait();
}
}
public synchronized void waitWhileEmpty()
throws InterruptedException {
while ( isQueueEmpty() ) {
wait();
}
}
public synchronized void waitUntilFull()
throws InterruptedException {
while ( !isFull() ) {
wait();
}
}
public synchronized void waitWhileFull()
throws InterruptedException {
while ( isFull() ) {
wait();
}
}
}