Files
sydapi/src/main/java/com/sunyard/pool/ThreadBasedConnectPool.java
T
2022-10-26 17:44:10 +08:00

126 lines
3.4 KiB
Java

package com.sunyard.pool;
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<Thread, ObjectInPool<T>>();
// 守护
private final ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(1);
// 配置
private PoolConfig config;
public ThreadBasedConnectPool(final PoolConfig config) {
this.config = config;
threadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
// 检测和回收逻辑
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()) {
// 长时间未使用,回收链接
it.remove();
try {
free(oip.getObject());
} catch (Exception e) {
}
continue;
}
boolean checkPass = false;
try {
checkPass = check(entry.getValue().getObjectForCheck());
} catch (Exception e) {
checkPass = false;
}
finally {
}
if ( ! checkPass) {
// 检查未通过
it.remove();
try {
free(oip.getObject());
} catch (Exception e) {
}
continue;
}
}
}
}, 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<T>(o));
}
// 清除
public void remove() {
map.remove(Thread.currentThread());
}
protected void afterInit(ObjectInPool oip, T value ){
}
private T setInitialValue() {
T value = initialValue();
ObjectInPool opi = new ObjectInPool<T>(value);
map.put(Thread.currentThread(), opi);
afterInit( opi , value);
return value;
}
}