构建数据库连接池

1.下面我们就使用等待超时模式构造简单数据库连接池,模拟从连接池中获取,使用和释放连接的过程,而客户端获取连接的过程被设定为等待超时模式,在1000 ms内无法获取到可用连接将会返回给客户端一个null,设定连接池大小为10,然后通过调节客户端线程数来模拟无法获取连接的场景。
2.连接池的定义:
通过构造函数初始化最大的连接上限,通过双向队列来维护连接,调用方先调用fetchConnection(long)方法来指定多少毫秒内超时获取连接,当连接使用完成后调用releaseConnectiion(Connection)方法将连接放回线程池。
3.代码
ConnectionPool.java

package connectionpool;
import java.util.*;
import java.sql.*;
public class ConnectionPool {

    private LinkedList<Connection> pool=new LinkedList<Connection>();
    public ConnectionPool(int initialSize)
    {//构造initialSize个线程的线程池
        if(initialSize>0)
        {
            for(int i=0;i<initialSize;i++)
            {
                pool.addLast(ConnectionDriver.createConnection());
            }
        }
    }


    public void releaseConnection(Connection connection)
    {//连接释放后使用notifyAll通知其他线程并将释放的连接放回到连接池
        if(connection!=null)
        {
            synchronized(pool)
            {
                pool.addLast(connection);
                pool.notifyAll();
            }
        }
    }
    public Connection fetchConnection(long mills) throws InterruptedException
    {//在mills毫秒内无法获取连接就返回null
        synchronized(pool)
        {
            if(mills<=0)
            {//完全超时
                while(pool.isEmpty())
                {//连接池为空,等待
                    pool.wait();
                }
                return pool.removeFirst();//返回获取的连接
            }
            else
            {
                long future=System.currentTimeMillis()+mills;
                long remaining=mills;
                while(pool.isEmpty()&&remaining>0)
                {
                    pool.wait(remaining);
                    remaining=future-System.currentTimeMillis();
                }
                Connection result=null;
                if(!pool.isEmpty())
                {
                    result=pool.removeFirst();
                }
                return result;
            }
        }
    }
}
package connectionpool;
import java.lang.reflect.*;
import java.util.concurrent.TimeUnit;
import java.sql.*;
public class ConnectionDriver 
{
    static class ConnectionHandler implements InvocationHandler
    {
        public Object invoke(Object proxy,Method method,Object[] args) throws Throwable
        {
            if(method.getName().equals("commit"))
            {
                TimeUnit.MILLISECONDS.sleep(100);
            }
            return null;
        }
    }
    public static final Connection createConnection()
    {
        return (Connection) Proxy.newProxyInstance(ConnectionDriver.class.getClassLoader(),new Class<?>[]{Connection.class},new ConnectionHandler());
    }
}
package connectionpool;
import java.util.*;
import java.sql.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class ConnectionPoolTest {
    static ConnectionPool pool=new ConnectionPool(10);//创建连接池
    static CountDownLatch start=new CountDownLatch(1);
    static CountDownLatch end;
    public static void main(String []args) throws Exception
    {
        int threadCount=10;
        end=new CountDownLatch(threadCount);
        int count=20;
        AtomicInteger got=new AtomicInteger();
        AtomicInteger notgot=new AtomicInteger();
        for(int i=0;i<threadCount;i++)
        {
            Thread thread=new Thread(new ConnectionRunner(count,got,notgot),"ConnectionRunnerThread");
            thread.start();
        }
        start.countDown();
        end.await();//当计数器减为0就不再阻塞
        System.out.println("total invoke:"+(threadCount*count));
        System.out.println("got connection:"+got);
        System.out.println("not got connection "+notgot);
    }
    static class ConnectionRunner implements Runnable
    {
        int count;
        AtomicInteger got;//连接获取的数量
        AtomicInteger notgot;//连接未获取的数量
        public ConnectionRunner(int count,AtomicInteger got,AtomicInteger notgot)
        {
            this.count=count;
            this.got=got;
            this.notgot=notgot;
        }
        @Override
        public void run()
        {
            try
            {
                start.await();
            }
            catch(Exception ex)
            {
            }
            while(count>0)
            {
                try
                {
                    Connection connection=pool.fetchConnection(1000);//从连接池获取连接并设置超时时间间隔
                    if(connection!=null)
                    {
                        try
                        {
                        //操作数据库并提交操作
                            connection.createStatement();
                            connection.commit();
                        }finally{
                        //操作完后释放连接并放回连接池
                            pool.releaseConnection(connection);
                            got.incrementAndGet();//获取到连接的数量加1
                        }
                    }
                    else
                    {//未成功获取到连接则notgot加1
                        notgot.incrementAndGet();
                    }
                }catch(Exception ex){}
                finally{
                    count--;
                }
            }
            end.countDown();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值