package com.xyz.connpool; public interface IConnection { /** * 关闭当前连接 */ public void close(); /** * 销毁当前连接 */ public void destroy(); //应该具备的其他方法 }
public class Connection implements IConnection { private String name; private IConnPool connPool; public Connection(IConnPool connPool,String name){ this.connPool=connPool; this.name=name; } @Override public void close() { this.connPool.releaseConn(this); } @Override public void destroy() { System.out.println("destroy connection---"+name); } @Override public String toString() { // TODO Auto-generated method stub super.toString(); return name; } }
public interface IConnPool { /** * 获得一个可用连接,超过最大连接数时线程等待,直到有有连接释放时返回一个可用连接或者超时返回null * @param maxWaitTime * @return */ public IConnection getConn(); /** * 将释放的空闲连接加入空闲连接池 * @param conn */ public void releaseConn(IConnection conn); /** * 销毁连接池 */ public void destroy(); /** * 获取当前线程对应的连接 * @return */ public IConnection getCurrentConn(); }
import java.util.ArrayList; import java.util.List; import java.util.UUID; public class ConnPool implements IConnPool { private int initNum; private int maxNum; private int hasAlready; private long maxWaitTime; private final List<IConnection> freeConnList; private final List<IConnection> activeConnList; private static ThreadLocal<IConnection> threadLocalVar=new ThreadLocal<IConnection>(){ protected IConnection initialValue() { return null; }; }; public ConnPool(){ this.initNum=3; this.maxNum=5; this.hasAlready=0; this.maxWaitTime=1000; this.freeConnList=new ArrayList<IConnection>(maxNum); this.activeConnList=new ArrayList<IConnection>(maxNum); init(); } public ConnPool(int initNum,int maxNum,long maxWaitTime){ this.initNum=initNum; this.maxNum=maxNum; this.hasAlready=0; this.maxWaitTime=maxWaitTime; this.freeConnList=new ArrayList<IConnection>(maxNum); this.activeConnList=new ArrayList<IConnection>(maxNum); init(); } private void init(){ for(int i=0;i<this.initNum;i++){ synchronized (this) { this.freeConnList.add(new Connection(this,UUID.randomUUID().toString())); hasAlready++; } } } @Override public synchronized IConnection getConn() { IConnection conn=null; if(!this.freeConnList.isEmpty()){ conn=this.freeConnList.remove(0); if(conn!=null) threadLocalVar.set(conn);//为线程绑定连接 this.activeConnList.add(conn); return conn; } if(hasAlready<maxNum){ conn = new Connection(this,UUID.randomUUID().toString()); hasAlready++; if(conn!=null) threadLocalVar.set(conn);//为线程绑定连接 this.activeConnList.add(conn); return conn; } try { this.wait(maxWaitTime); if(!this.freeConnList.isEmpty()){ conn=this.freeConnList.remove(0); if(conn!=null) threadLocalVar.set(conn);//为线程绑定连接 this.activeConnList.add(conn); return conn; } return null; } catch (InterruptedException e) { e.printStackTrace(); return null; } } @Override public synchronized void releaseConn(IConnection conn) { if(this.activeConnList.contains(conn)){ this.freeConnList.add(conn); this.activeConnList.remove(conn); threadLocalVar.remove(); this.notify(); } } @Override public synchronized void destroy() { IConnection conn=null; int temp=this.freeConnList.size(); for(int i=0;i<temp;i++){ conn=this.freeConnList.remove(0); conn.destroy(); } temp=this.activeConnList.size(); for(int i=0;i<temp;i++){ conn=this.activeConnList.remove(0); conn.destroy(); } conn=null; this.hasAlready=0; } @Override public IConnection getCurrentConn() { return threadLocalVar.get(); } }
package com.xyz.connpool; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class ConnPoolManager { private int initConnNum; private int maxConnNum; private long maxWaitTime; // 连接池存放 public Map<Integer,IConnPool> pools=new ConcurrentHashMap<Integer, IConnPool>(); // public Hashtable<Integer,IConnPool> pools = new Hashtable<Integer, IConnPool>(); public ConnPoolManager(int initConnNum,int maxConnNum, long maxWaitTime){ this.initConnNum=initConnNum; this.maxConnNum=maxConnNum; this.maxWaitTime=maxWaitTime; init(); } // 初始化所有的连接池 private void init(){ for(int hostId =0;hostId<3;hostId++){ ConnPool connPool=new ConnPool(this.initConnNum,this.maxConnNum, this.maxWaitTime); if(connPool != null){ pools.put(hostId,connPool); System.out.println("Info:Init connPool successed for hostId ->" +hostId); } } } /** * 根据主机id获取连接池 * @param hostId * @return */ public IConnPool getPool(int hostId){ IConnPool pool = null; if(pools.containsKey(hostId)){ pool = pools.get(hostId); } return pool; } /** * 获取一个到主机hostId的连接 * @param hostId * @return */ public IConnection getConn(int hostId){ IConnPool connPool = getPool(hostId); if(connPool==null){ System.out.println("Error:Can't find this connecion pool for hostId->"+hostId); return null; } return connPool.getConn(); } /** * 关闭指定主机的某个链接 * @param hostId * @param conn */ public void close(int hostId,IConnection conn){ IConnPool pool = getPool(hostId); if(pool != null) pool.releaseConn(conn); } /** * 注销某个主机的连接池 * @param poolName */ public void destroy(int hostId){ IConnPool pool = getPool(hostId); if(pool != null){ pool.destroy(); } pools.remove(pool); } /** * 注销所有连接池 */ public void destory(){ for(int hostId:pools.keySet()){ this.destroy(hostId); } } }
package com.xyz.connpool; import java.util.concurrent.CountDownLatch; public class Demo { public final static int REQUESTNUM=200; public final static int DURATION=20; public static void main(String [] args) throws Exception{ final CountDownLatch startGate=new CountDownLatch(1); final CountDownLatch endGate=new CountDownLatch(REQUESTNUM); final ConnPoolManager cpm=new ConnPoolManager(5, 10, 1000); final IConnection conns[] =new IConnection[REQUESTNUM]; for(int i=0;i<REQUESTNUM;i++){ final int flag=i; new Thread(new Runnable() { @Override public void run() { try { startGate.await(); } catch (InterruptedException e1) {} conns[flag]=cpm.getConn(0); System.out.println(conns[flag]); try { Thread.sleep(DURATION); } catch (InterruptedException e) {} cpm.close(0, conns[flag]); endGate.countDown(); } }).start(); } long begin = System.currentTimeMillis(); startGate.countDown(); endGate.await(); long over = System.currentTimeMillis(); System.out.println(over-begin); // Thread.sleep(5000); cpm.destory(); } }
源代码下载 https://github.com/ZhenShiErGe/ConnectionPool.git