sydapi-java-sge-database/src/main/java/com/sunyard/sge/pool/ThreadBasedConnectPool.java
2022-08-15 15:35:06 +08:00

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;
}
}