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 { // ThreadLocal private final Map> 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>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry> entry = it.next(); ObjectInPool 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 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; } }