简洁高效的数据库连接池

      最近在IBM websphere portal的项目中,碰到大量的portlet需要连接数据库,而连接数据库的开销造成性能问题,因此考虑在portal中使用连接池。方案1)使用portal的连接池,可惜IBM的连接池使用起来很是不爽,问题多多,放弃。方案2)自己写连接池,其实质是connection对象池。在portal 项目中开发连接池,要解决的问题,是数据库驱动程序的位置。本方案借助于连接创建和连接池分开的方法实现。

       本应用包含三个类,如下:

        ConnectionPool   连接池管理类

        AddConnectionProcess  连接维护线程类

        DbSource  创建数据库连接接口类

        public class ConnectionPool {

    private Vector pool = new Vector();

    private String name;//暂时没有使用
    private int maxConn;//最大连接数
    private int normalConn;//正常连结数
    private int minConn;//最小连接数
    private DbSource dbSource;

    private boolean addThreadFlag = false;

    private  static ConnectionPool instance=null;

    private void init(DbSource dbSource,String name, int maxConn, int normalConn, int minConn) throws Exception {
        this.name = name;
        this.maxConn=maxConn;
        this.normalConn = normalConn;
        this.minConn = minConn;
        this.dbSource=dbSource;
        addThreadFlag = true;
        Thread thread = new Thread(new AddConnectionProcess(this));//初始化连接池
        thread.start();
    }

    public static ConnectionPool getInstance(DbSource dbSource,  int maxConn, int normalConn,int minConn)throws Exception {
       if(instance==null){
        synchronized(ConnectionPool.class){
            if(instance==null){
                instance = new ConnectionPool();
                instance.init(dbSource,"DB2",maxConn,normalConn,minConn);
            }
        }
       }
       return instance;

    }
    public static ConnectionPool getInstance(){
       return instance;
    }

   /**
     * 将不再使用的连接返回给连接池
     *
     * @param conn 客户程序释放的连接

    * @param repeat连接重复使用标志

     */
    public synchronized void freeConnection(Connection conn, boolean repeat) {
        // 将指定连接加入到向量末尾
        if(conn==null)
            return;
        if (repeat && pool.size()<maxConn)
            pool.add(conn);
        else {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //notifyAll();
    }


    /**
     * 考虑到线程的执行效率,在这里不考虑连接的有效性
     * 注意:连接的有效性需要各自线程负责
     */
     public synchronized Connection getConnection() {

        Connection con = null;
        if (pool.size() > 0) {
            // 获取向量中第一个可用连接
            con=(Connection)pool.remove(0);
            if (pool.size() < minConn) {
                //小于最小连接数时,触发获取连接的线程操作
                if (!addThreadFlag) {
                    addThreadFlag = true;
                    Thread thread = new Thread(new AddConnectionProcess(this));
                    thread.start();
                }
            }
        } else {
            try {
                con = dbSource.newConnection();
            } catch (Exception e) {
               e.printStackTrace();
            }
        }
        return con;
    }

   //释放连结

   public synchronized void release() {
        Enumeration allConnections = pool.elements();
        while (allConnections.hasMoreElements()) {
            Connection con = (Connection) allConnections.nextElement();
            try {
                con.close();

            }catch (SQLException e) {
              e.printStackTrace();
            }
        }
        pool.removeAllElements();
    }

 

    public int getNormalConn() {
        return normalConn;
    }

    public String getName() {
        return name;
    }

    public int getMinConn() {
        return minConn;
    }


    public Vector getPool() {
        return pool;
    }


    public boolean getAddThreadFlag() {
        return addThreadFlag;
    }

    public void setAddThreadFlag(boolean addThreadFlag) {
        this.addThreadFlag = addThreadFlag;
    }


    public DbSource getDbSource() {
        return dbSource;
    }
}

//创建连接线程类

public class AddConnectionProcess implements Runnable{
    private  ConnectionPool connectionPool;
    public  AddConnectionProcess(ConnectionPool pool){
       this.connectionPool =pool;
    }
    //更新到最大连接数
    public void run() {
        System.out.println("running add connection");
        Vector conns=new Vector();

        int num=connectionPool.getNormalConn()-connectionPool.getPool().size();
        try{
            while(num>0){
                Connection conn= connectionPool.getDbSource().newConnection();
                if(conn!=null){
                    //conn.setAutoCommit(false);
                    //conn.setReadOnly(true);
                    conns.add(conn);

                    num--;
                }
            }
        }catch(Exception e){
            try{
             Thread.sleep(60*1000);
            }catch(Exception e2){
               e2.printStackTrace();
            }
        }
        Vector pool=connectionPool.getPool();
        pool.addAll(conns);
        connectionPool.setAddThreadFlag(false);
    }


}

 

//数据库连接接口

public interface DbSource {
    public Connection newConnection() throws Exception;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值