131 lines
3.6 KiB
Java
131 lines
3.6 KiB
Java
package com.sunyard.sge.pool;
|
|
|
|
import com.sunyard.sge.log.LogFactory;
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.Map;
|
|
import java.util.concurrent.Executors;
|
|
import java.util.concurrent.ScheduledExecutorService;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
public class ThreadBasedConnectPool<T> {
|
|
|
|
|
|
// ThreadLocal
|
|
private final Map<Thread, ObjectInPool<T>> map = new HashMap<>();
|
|
|
|
// 守护
|
|
private final ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(1);
|
|
|
|
// 配置
|
|
private PoolConfig config;
|
|
|
|
public ThreadBasedConnectPool(PoolConfig config) {
|
|
this.config = config;
|
|
threadPool.scheduleAtFixedRate(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
Logger log = LogFactory.getLogger();
|
|
log.debug("连接池检测进程开始执行");
|
|
log.debug("共有链接 {} 个", map.size());
|
|
|
|
// 检测和回收逻辑
|
|
Iterator<Map.Entry<Thread, ObjectInPool<T>>> it = map.entrySet().iterator();
|
|
while (it.hasNext()) {
|
|
Map.Entry<Thread, ObjectInPool<T>> entry = it.next();
|
|
ObjectInPool<T> oip = entry.getValue();
|
|
|
|
if (System.currentTimeMillis() - oip.getLasUseAt() < config.getMaxIdle()) {
|
|
// 空闲时间不足,免检。
|
|
continue;
|
|
}
|
|
|
|
if (System.currentTimeMillis() - oip.getLasUseAt() > config.getMaxUseless()) {
|
|
// 长时间未使用,回收链接
|
|
log.debug("回收一个链接");
|
|
|
|
it.remove();
|
|
|
|
try {
|
|
free(oip.getObject());
|
|
} catch (Exception e) {
|
|
}
|
|
continue;
|
|
}
|
|
|
|
boolean checkPass = false;
|
|
try {
|
|
checkPass = check(entry.getValue().getObjectForCheck());
|
|
} catch (Exception e) {
|
|
checkPass = false;
|
|
}
|
|
|
|
if ( ! checkPass) {
|
|
log.debug("一个链接检查未通过");
|
|
// 检查未通过
|
|
it.remove();
|
|
|
|
try {
|
|
free(oip.getObject());
|
|
} catch (Exception e) {
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
|
|
log.debug("连接池检测进程执行结束");
|
|
}
|
|
}, config.getMaxIdle(), config.getMaxIdle(), TimeUnit.MILLISECONDS);
|
|
}
|
|
|
|
public ThreadBasedConnectPool() {
|
|
this(new PoolConfig());
|
|
}
|
|
|
|
// 继承 初始化
|
|
protected T initialValue() {
|
|
return null;
|
|
}
|
|
|
|
|
|
// 保活接口
|
|
protected boolean check(T o) {
|
|
return null != o;
|
|
}
|
|
|
|
// 释放
|
|
protected void free(T o) {
|
|
}
|
|
|
|
|
|
// 获取
|
|
public T get() {
|
|
ObjectInPool<T> o = map.get(Thread.currentThread());
|
|
if (null != o) {
|
|
return o.getObject();
|
|
}
|
|
|
|
return setInitialValue();
|
|
}
|
|
|
|
// 设置
|
|
public void set(T o) {
|
|
map.put(Thread.currentThread(), new ObjectInPool<>(o));
|
|
}
|
|
|
|
// 清除
|
|
public void remove() {
|
|
map.remove(Thread.currentThread());
|
|
}
|
|
|
|
|
|
private T setInitialValue() {
|
|
T value = initialValue();
|
|
map.put(Thread.currentThread(), new ObjectInPool<>(value));
|
|
return value;
|
|
}
|
|
}
|