📄 connectionpool.java
字号:
package dateBaseConnectionPool;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Date;
import java.util.Calendar;
import dateBaseConnectionPool.poolException.*;
public class ConnectionPool {
/**
* <b>独占方式</b><br>
* 使用空闲的实际连接分配连接资源,并且在该资源释放回之前,该资源在连接池中将不能将其引用分配给其他申请者。<br>
* 如果连接池中所有实际连接资源都已经分配出去,那么即使连接池可以在分配引用资源在该模式下连接迟将不会分配连接资源,
* 连接池会产生一个异常,标志连接池资源耗尽。<br><br>
* <font color='#006600'>例:假如一个实际连接可以被分配5次,那么使用该模式申请连接的话您将损失4个可分配的连接,只将得到一个连接资源。
* 直至该资源被释放回连接池,连接池才继续分配它剩余的4次机会。</font>
* <br><br>
* 当您在使用连接时可能应用到事务时,可以使用该模式的连接,以确定在事务进行期间您可以对该连接具有独享权限,以避免各个数据库操作访问的干扰。
*/
public static final int ConnLevel_ReadOnly = 10;
/**
* <b>优先级-高</b><br>
* 使用空闲的实际连接分配连接资源,并且在该资源释放回之前,该资源在连接池中将可能将其引用分配给其他申请者。<br>
* <font color='#FF0000'>*注意:此级别不保证在分配该资源后,仍然保持独立占有连接资源,若想独立占有资源请使用ReadOnely,
* 因为当连接池达到某一时机时该资源将被重复分配(引用记数)然而这个时机是不可预测的。</font><br>
* 如果您申请的连接会用于事务处理您可以使用<font color='#0033CC'>ConnLevel_ReadOnly</font>级别
*/
public static final int ConnLevel_High = 11;
/**
* <b>优先级-中</b><br>
* 适当应用引用记数技术分配连接资源。<br>
* 在该模式下,连接池内部会按照实际连接已经使用次数排序(多->少),然后在结果中选取 1/3 位置的连接资源返回。<br>
* 与优先级-高相同该模式也不具备保持独立占有连接资源的特性。<br>
* 如果您申请的连接会用于事务处理您可以使用<font color='#0033CC'>ConnLevel_ReadOnly</font>级别
*/
public static final int ConnLevel_None = 12;
/**
* <b>优先级-底</b><br>
* 尽可能使用引用记数技术分配连接。<br>
* 在该模式下,连接池内部会按照实际连接已经使用次数排序(多->少),然后在结果中选取被使用最多的返回。<br>
* 该模式适合处理较为不重要的连接资源请求。<br>
* 与优先级-高相同该模式也不具备保持独立占有连接资源的特性。<br>
* 如果您申请的连接会用于事务处理您可以使用<font color='#0033CC'>ConnLevel_ReadOnly</font>级别
*/
public static final int ConnLevel_Bottom = 13;
/**
* 表示未对连接池未被调用过StartSeivice方法。
*/
public static final int PoolState_UnInitialize = 20;
/**
* 连接池初始化中,该状态下服务正在按照参数初始化连接池。StopServices之后将首先跳转到该状态
*/
public static final int PoolState_Initialize = 21;
/**
* 当连接池开始运做时则表示为该状态
*/
public static final int PoolState_Run = 22;
/**
* 连接池被调用StopServices停止状态
*/
public static final int PoolState_Stop = 23;
//属性
private int _RealFormPool; //连接池中存在的实际连接数(包含失效的连接)
private int _PotentRealFormPool; //连接池中存在的实际连接数(有效的实际连接)
private int _SpareRealFormPool; //空闲的实际连接
private int _UseRealFormPool; //已分配的实际连接
private int _ReadOnlyFormPool; //连接池已经分配多少只读连接
private int _UseFormPool; //已经分配出去的连接数
private int _SpareFormPool; //目前可以提供的连接数
private int _MaxConnection; //最大连接数,最大可以创建的连接数目
private int _MinConnection; //最小连接数
private int _SeepConnection; //每次创建连接的连接数
private int _KeepRealConnection; //保留的实际空闲连接,以攻可能出现的ReadOnly使用,当空闲连接不足该数值时,连接池将创建seepConnection个连接
private int _Exist = 20; //每个连接生存期限 20分钟
private String _userID="";
private String _password="";
//可以被重复使用次数(引用记数),当连接被重复分配该值所表示的次数时,该连接将不能被分配出去
//当连接池的连接被分配尽时,连接池会在已经分配出去的连接中,重复分配连接(引用记数)。来缓解连接池压力
private int _MaxRepeatDegree = 5;
private Date _StartTime; //服务启动时间
private String _ConnString = null; //连接字符串
private String _DriveString = null; //驱动字符串
private int _PoolState; //连接池状态
//内部对象
private ArrayList<ConnStruct> al_All = new ArrayList<ConnStruct>(); //实际连接
private Hashtable<Object, ConnStruct> hs_UseConn = new Hashtable<Object, ConnStruct>(); //正在使用的连接
private CreateThreadProcess threadCreate;
private CheckThreadProcess threadCheck;
//-------------------------------------------------------------------------------------------
/**
* 初始化连接池
*/
public ConnectionPool() {
InitConnectionPool("", "", 200, 30, 10, 5);
}
/**
* 初始化连接池
* @param connectionString String 数据库连接字符串。
* @param driveString String 数据库驱动字符串。
*/
public ConnectionPool(String connectionString, String driveString) {
InitConnectionPool(connectionString, driveString, 200, 30, 10, 5);
}
/**
* 初始化连接池
* @param connectionString String 数据库连接字符串。
* @param driveString String 数据库驱动字符串。
* @param maxConnection int 最大实际连接数,最大可以创建的连接数目。
* @param minConnection int 最小实际连接数。
*/
public ConnectionPool(String connectionString, String driveString, int maxConnection, int minConnection) {
InitConnectionPool(connectionString, driveString, maxConnection, minConnection, 10, 5);
}
/**
* 初始化连接池
* @param connectionString String 数据库连接字符串。
* @param driveString String 数据库驱动字符串。
* @param maxConnection int 最大实际连接数,最大可以创建的连接数目。
* @param minConnection int 最小实际连接数。
* @param seepConnection int 每次创建连接的连接数。当空闲的实际连接不足该值时创建连接,直到达到最大连接数
* @param keepRealConnection int 保留连接数,当空闲连接不足该数值时,连接池将创建seepConnection个连接。
*/
public ConnectionPool(String connectionString, String driveString, int maxConnection, int minConnection, int seepConnection, int keepRealConnection) {
InitConnectionPool(connectionString, driveString, maxConnection, minConnection, seepConnection, keepRealConnection);
}
/**
* 初始化连接池
* @param connectionString String 数据库连接字符串。
* @param driveString String 数据库驱动字符串。
* @param maxConnection int 最大实际连接数,最大可以创建的连接数目。
* @param minConnection int 最小实际连接数。
* @param seepConnection int 每次创建连接的连接数。当空闲的实际连接不足该值时创建连接,直到达到最大连接数
* @param keepRealConnection int 保留连接数,当空闲连接不足该数值时,连接池将创建seepConnection个连接。
*/
private void InitConnectionPool(String connectionString, String driveString, int maxConnection, int minConnection, int seepConnection, int keepRealConnection) {
this._PoolState = PoolState_UnInitialize;
this._ConnString = connectionString;
this._DriveString = driveString;
this._MinConnection = minConnection;
this._SeepConnection = seepConnection;
this._KeepRealConnection = keepRealConnection;
this._MaxConnection = maxConnection;
this.threadCheck = new CheckThreadProcess();
this.threadCheck.setDaemon(true);
this.threadCreate = new CreateThreadProcess();
this.threadCreate.setDaemon(true);
this.threadCheck.start();
while(threadCheck.getState()!=Thread.State.WAITING){}
}
//-------------------------------------------------------------------------------------------
/**
* <p>创建线程类</p>
*/
private class CreateThreadProcess extends Thread {
public int createThreadMode = 0; //创建线程工作模式
public int createThreadProcessTemp = 0; //需要创建的连接数
public boolean createThreadProcessRun = false; //是否决定创建线程将继续工作,如果不继续工作则线程会将自己处于阻止状态
public void run() {
boolean join = false;
int createThreadProcessTemp_inside = createThreadProcessTemp;
_PoolState = PoolState_Initialize;
while (true)
{
join = false;
_PoolState = PoolState_Run;
if (createThreadProcessRun == false)
{//遇到终止命令
try {
this.join();//中断自己
} catch (Exception e) {/* */}
}
else
{
if (createThreadMode == 0)
{
//------------------------begin mode 创建模式
synchronized (al_All)
{
if (al_All.size() < createThreadProcessTemp_inside)
al_All.add(CreateConnectionTemp(_ConnString,_DriveString,_userID,_password));
else
join = true;
}
//------------------------end mode
}
else if (createThreadMode == 1)
{
//------------------------begin mode 增加模式
synchronized (al_All)
{
if (createThreadProcessTemp_inside != 0)
{
createThreadProcessTemp_inside--;
al_All.add(CreateConnectionTemp(_ConnString,_DriveString,_userID,_password));
}
else
join = true;
}
//------------------------end mode
}
else
join = true;
//-------------------------------------------------------------------------
if (join == true)
{
UpdateAttribute();//更新属性
try {
createThreadProcessTemp = 0;
this.join(); //中断自己
} catch (Exception e) {
createThreadProcessTemp_inside = createThreadProcessTemp;
} //得到传入的变量
}
}
}
}
}
/**
* <p>检测事件</p>
*/
private class CheckThreadProcess extends Thread {
private long _Interval = 100; //执行间隔
private boolean timeSize=false;
/**
* 启动记时器
*/
public void StartTimer()
{
timeSize=true;
if (this.getState()==Thread.State.NEW)
this.start();
else if (this.getState()==Thread.State.WAITING)
this.interrupt();
}
/**
* 停止记时器
*/
public void StopTimer()
{
timeSize=false;
while(this.getState()!=Thread.State.WAITING){/**/}
}
public void aRun()
{
ConnStruct cs = null;
//如果正在执行创建连接则退出
if (threadCreate.getState() != Thread.State.WAITING)
return;
//------------------------------------------------------
synchronized (al_All)
{
for (int i = 0; i < al_All.size(); i++)
{
cs = al_All.get(i);
TestConnStruct(cs);//测试
if (cs.GetEnable() == false && cs.GetRepeatNow() == 0)//没有引用的失效连接
{
cs.Close();//关闭它
al_All.remove(cs);//删除
}
}
}
//------------------------------------------------------
UpdateAttribute();//更新属性
if (_SpareRealFormPool < _KeepRealConnection)//保留空闲实际连接数不足
threadCreate.createThreadProcessTemp = GetNumOf(_RealFormPool, _SeepConnection, _MaxConnection);
else
threadCreate.createThreadProcessTemp = 0;
//if (threadCreate.createThreadProcessTemp != 0)
//{
// System.out.println("创建" + threadCreate.createThreadProcessTemp);
// System.out.println(threadCreate.getState()+ " this " + this.getState());
//}
if (threadCreate.createThreadProcessTemp != 0)
{
//启动创建线程,工作模式1
threadCreate.createThreadMode = 1;
threadCreate.interrupt();
}
}
public void run() {
while (true) {
try {
this.join(_Interval);
if (timeSize == true)
aRun();
else
this.join();
} catch (InterruptedException ex1) {/**/ }
}
}
/**
* 设置执行时间间隔
* @param value double 时间间隔
*/
public void setInterval(long value) {
_Interval = value;
}
/**
* 获得执行时间间隔
* @return double 时间间隔
*/
public long getInterval() {
return _Interval;
}
/**
* 得到当前要增加的量
* @param nowNum int 当前值
* @param seepNum int 步长
* @param maxNum int 最大值
* @return int 当前要增加的量
*/
private int GetNumOf(int nowNum, int seepNum, int maxNum) {
if (maxNum >= nowNum + seepNum)
return seepNum;
else
return maxNum - nowNum;
}
}
//-------------------------------------------------------------------------------------------
/**
* 设置连接池字符串
* @param _ConnString String 连接字符串
* @param _DriveString String 驱动字符串
* @throws StateException 服务状态错误
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -