池化对象工厂(PooledObjectFactory)
/**
* 创建一个新对象
*
* 当对象池中的对象个数不足时,将会使用此方法来创建一个新的"对象",并交付给对象池管理。
*/
PooledObject<T> makeObject() throws Exception;
/**
* 销毁对象
*
* 如果对象池检测到某个"对象"空闲超时,或者操作者向对象池归还"对象"时检测到"对象"已经无效,那么会将对象销毁;
* "销毁对象"的操作设计相差甚远,但是有一点必须明确:当调用此方法时,"对象"的生命周期必须结束。
* 如果"对象"是线程,那么此时线程必须退出;
* 如果"对象"是 socket,那么此时 socket 必须关闭;
* 如果"对象"是文件流,那么此时需要对数据进行 flush,然后将文件流正常关闭.
*/
void destroyObject(PooledObject<T> p) throws Exception;
/*
* 检测对象的有效性
*
* 所谓有效性,就是指此"对象"的状态是否符合预期,是否可以直接使用。
* 对象池不能保存无效的"对象",因此"后台检测线程"会周期性的检测对象池中"对象"的有效性,如果对象无效则会导致此对象从池中移除,并销毁;
* 在调用者从池中获取一个"对象"时,也会检测"对象"的有效性,确保不能将"无效"的对象返回给调用者;
* 当调用者将"对象归还"给对象池时,仍然会检测对象的有效性。
* 比如对象是 socket,那么它的有效性就是 socket 的通道是否畅通、阻塞是否超时等。
*/
boolean validateObject(PooledObject<T> p);
/**
* 激活对象
*
* 当对象池决定移除一个对象交付给调用者时需要额外的"激活"操作,比如可以在 activateObject 方法中"重置"参数让调用者使用时感觉像一个"新创建的对象"一样;
* 如果对象是一个线程,可以在"激活"操作中重置"线程中断标记",或者让线程从阻塞中唤醒等;
* 如果对象是一个 socket,那么可以在"激活操作"中刷新通道,或者对 socket 的链接进行重建(例如 socket 意外关闭)等。
*/
void activateObject(PooledObject<T> p) throws Exception;
/*
* 钝化对象
*
* 当调用者"归还对象"时,对象池会对"对象"进行钝化操作;钝化的言外之意,就是此"对象"需要暂时"休息"一下。
* 如果对象是一个 socket,那么可以在 passivateObject 方法中清除buffer,将socket阻塞;
* 如果对象是一个线程,可以在 passivateObject 方法中将线程 sleep 或者将线程中的某个对象阻塞。需要注意的是 activateObject 和 passivateObject 两个方法需要一一对应,避免死锁或者"对象"状态的混乱。
*/
void passivateObject(PooledObject<T> p) throws Exception;