准备工作
1:创建连接的工具类PoolUtil,静态方法get()返回比如jdbc的连接对象Connection;
2:创建测试类,模拟并发环境。测试类中使用CountDownLatch的一个实例化对象cdl,new的时候指定并发数比如10,每次线程中cdl.countDown();实现计数器减一,然后cdl.await()阻塞直至等于0,然后就相当于10个请求同步进入;
CountDownLatch countDownLatch=new CountDownLatch(10);
countDownLatch.countDown();//调用一次,这个计数器就减一
countDownLatch.await();//阻塞,直至等于0,然后放行
开始
//这就是连接池
public class Pool{
//两个队列,一个idle表示空闲队列,一个busy表示忙碌队列
private LinkedBlockingQueue idle;
private LinkedBlockingQueue busy;
//int的原子类对象,实现线程安全
private AtomicInteger activeSize;
//指定最大连接数
private final int MAXSIZE = 10;
//1:初始化的方法
public void init(){
idle=new LinkedBlockingQueue();
busy=new LinkedBlockingQueue();
}
//2:销毁的方法
public void destroy(){
idle=null;
busy=null;
}
//3:返回一个连接对象的方法
public Connection get() {
//首先从idle中返回一个,
Connection conn= (Connection) idle.poll();
if(conn != null){
return conn;
}
//idle中没有,判断是不是已经够10;不够就新建
if(activeSize.get() < MAXSIZE){
if(activeSize.incrementAndGet()<=MAXSIZE){
conn =PoolUtil.get();
busy.offer(conn);
return conn;
}
}
//已经够10就阻塞, 超时就抛出异常
try {
conn= (Connection) idle.poll(10000, TimeUnit.MILLISECONDS);
if(null == conn){
throw new RuntimeException("等待超时");
} catch (InterruptedException e) {
e.printStackTrace();
}
return conn;
}
//4:归还一个连接,从busy中取出,从idle中加上
public void release(Connection connection){
busy.remove(connection);
idle.offer(connection);
}
//5:定时器,去检查空闲中的连接是否可用,不可用的话就换掉
@Scheduled(fixedRate = 60*1000)//定时器,每分钟检测一次
public void check() throws SQLException {
Iterator it=idle.iterator();
while (it.hasNext()){
Connection conn= (Connection) it.next();
boolean b=conn.isValid(2000);
if(!b){
idle.remove(conn);
idle.offer(PoolUtil.get());
}
}
}
}
然后调用时,只需Pool.get()即可得到连接对象;Pool.release(conn)归还一个连接;无需close,正常运行的时候也不需要创建新的连接;
如果你能看到这里,希望点个赞,最好在评论一下,让我知道并不孤单;