5、JAVA数据库连接池实现

转:http://greemranqq.iteye.com/blog/1969273
    在一个成套的web系统中,不能更改源代码的情况下,要进行频繁的数据库操作,需要进行数据库连接管理而不影响原系统运行,这里就是一个java实现连接池的demo:
    主要是对连接数的控制,比如最大20,最小2的连接。
package pool;  
import java.sql.Connection;  
import java.sql.SQLException;  
  
public interface IConnectionPool {  
    // 获得连接  
    public Connection  getConnection();  
    // 获得当前连接  
    public Connection getCurrentConnecton();  
    // 回收连接  
    public void releaseConn(Connection conn) throws SQLException;  
    // 销毁清空  
    public void destroy();  
    // 连接池是活动状态  
    public boolean isActive();  
    // 定时器,检查连接池  
    public void cheackPool();  
}  

package pool; 
 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.SQLException; 
import java.util.List; 
import java.util.Timer; 
import java.util.TimerTask; 
import java.util.Vector; 
 
public class ConnectionPool implements IConnectionPool { 
    // 连接池配置属性 
    private DBbean dbBean; 
    private boolean isActive = false; // 连接池活动状态 
    private int contActive = 0;// 记录创建的总的连接数 
     
    // 空闲连接 
    private List<Connection> freeConnection = new Vector<Connection>(); 
    // 活动连接 
    private List<Connection> activeConnection = new Vector<Connection>(); 
    // 将线程和连接绑定,保证事务能统一执行 
    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>(); 
     
    public ConnectionPool(DBbean dbBean) { 
        super(); 
        this.dbBean = dbBean; 
        init(); 
        cheackPool(); 
    } 
 
    // 初始化 
    public void init() { 
        try { 
            Class.forName(dbBean.getDriverName()); 
            for (int i = 0; i < dbBean.getInitConnections(); i++) { 
                Connection conn; 
                conn = newConnection(); 
                // 初始化最小连接数 
                if (conn != null) { 
                    freeConnection.add(conn); 
                    contActive++; 
                } 
            } 
            isActive = true; 
        } catch (ClassNotFoundException e) { 
            e.printStackTrace(); 
        } catch (SQLException e) { 
            e.printStackTrace(); 
        } 
    } 
     
    // 获得当前连接 
    public Connection getCurrentConnecton(){ 
        // 默认线程里面取 
        Connection conn = threadLocal.get(); 
        if(!isValid(conn)){ 
            conn = getConnection(); 
        } 
        return conn; 
    } 
 
    // 获得连接 
    public synchronized Connection getConnection() { 
        Connection conn = null; 
        try { 
            // 判断是否超过最大连接数限制 
            if(contActive < this.dbBean.getMaxActiveConnections()){ 
                if (freeConnection.size() > 0) { 
                    conn = freeConnection.get(0); 
                    if (conn != null) { 
                        threadLocal.set(conn); 
                    } 
                    freeConnection.remove(0); 
                } else { 
                    conn = newConnection(); 
                } 
                 
            }else{ 
                // 继续获得连接,直到从新获得连接 
                wait(this.dbBean.getConnTimeOut()); 
                conn = getConnection(); 
            } 
            if (isValid(conn)) { 
                activeConnection.add(conn); 
                contActive ++; 
            } 
        } catch (SQLException e) { 
            e.printStackTrace(); 
        } catch (ClassNotFoundException e) { 
            e.printStackTrace(); 
        } catch (InterruptedException e) { 
            e.printStackTrace(); 
        } 
        return conn; 
    } 
 
    // 获得新连接 
    private synchronized Connection newConnection() 
            throws ClassNotFoundException, SQLException { 
        Connection conn = null; 
        if (dbBean != null) { 
            Class.forName(dbBean.getDriverName()); 
            conn = DriverManager.getConnection(dbBean.getUrl(), 
                    dbBean.getUserName(), dbBean.getPassword()); 
        } 
        return conn; 
    } 
 
    // 释放连接 
    public synchronized void releaseConn(Connection conn) throws SQLException { 
        if (isValid(conn)&& !(freeConnection.size() > dbBean.getMaxConnections())) { 
            freeConnection.add(conn); 
            activeConnection.remove(conn); 
            contActive --; 
            threadLocal.remove(); 
            // 唤醒所有正待等待的线程,去抢连接 
            notifyAll(); 
        } 
    } 
 
    // 判断连接是否可用 
    private boolean isValid(Connection conn) { 
        try { 
            if (conn == null || conn.isClosed()) { 
                return false; 
            } 
        } catch (SQLException e) { 
            e.printStackTrace(); 
        } 
        return true; 
    } 
 
    // 销毁连接池 
    public synchronized void destroy() { 
        for (Connection conn : freeConnection) { 
            try { 
                if (isValid(conn)) { 
                    conn.close(); 
                } 
            } catch (SQLException e) { 
                e.printStackTrace(); 
            } 
        } 
        for (Connection conn : activeConnection) { 
            try { 
                if (isValid(conn)) { 
                    conn.close(); 
                } 
            } catch (SQLException e) { 
                e.printStackTrace(); 
            } 
        } 
        isActive = false; 
        contActive = 0; 
    } 
 
    // 连接池状态 
    @Override 
    public boolean isActive() { 
        return isActive; 
    } 
     
    // 定时检查连接池情况 
    @Override 
    public void cheackPool() { 
        if(dbBean.isCheakPool()){ 
            new Timer().schedule(new TimerTask() { 
            @Override 
            public void run() { 
            // 1.对线程里面的连接状态 
            // 2.连接池最小 最大连接数 
            // 3.其他状态进行检查,因为这里还需要写几个线程管理的类,暂时就不添加了 
            System.out.println("空线池连接数:"+freeConnection.size()); 
            System.out.println("活动连接数::"+activeConnection.size()); 
            System.out.println("总的连接数:"+contActive); 
                } 
            },dbBean.getLazyCheck(),dbBean.getPeriodCheck()); 
        } 
    } 


package pool; 
 
import java.sql.Connection; 
import java.sql.SQLException; 
import java.util.Hashtable; 
/**
* 连接管理类
* @author Ran
*
*/ 
public class ConnectionPoolManager { 
     
     
    // 连接池存放 
    public Hashtable<String,IConnectionPool> pools = new Hashtable<String, IConnectionPool>(); 
     
    // 初始化 
    private ConnectionPoolManager(){ 
        init(); 
    } 
    // 单例实现 
    public static ConnectionPoolManager getInstance(){ 
        return Singtonle.instance; 
    } 
    private static class Singtonle { 
        private static ConnectionPoolManager instance =  new ConnectionPoolManager(); 
    } 
     
     
    // 初始化所有的连接池 
    public void init(){ 
        for(int i =0;i<DBInitInfo.beans.size();i++){ 
            DBbean bean = DBInitInfo.beans.get(i); 
            ConnectionPool pool = new ConnectionPool(bean); 
            if(pool != null){ 
                pools.put(bean.getPoolName(), pool); 
                System.out.println("Info:Init connection successed ->" +bean.getPoolName()); 
            } 
        } 
    } 
     
    // 获得连接,根据连接池名字 获得连接 
    public Connection  getConnection(String poolName){ 
        Connection conn = null; 
        if(pools.size()>0 && pools.containsKey(poolName)){ 
            conn = getPool(poolName).getConnection(); 
        }else{ 
            System.out.println("Error:Can't find this connecion pool ->"+poolName); 
        } 
        return conn; 
    } 
     
    // 关闭,回收连接 
    public void close(String poolName,Connection conn){ 
            IConnectionPool pool = getPool(poolName); 
            try { 
                if(pool != null){ 
                    pool.releaseConn(conn); 
                } 
            } catch (SQLException e) { 
                System.out.println("连接池已经销毁"); 
                e.printStackTrace(); 
            } 
    } 
     
    // 清空连接池 
    public void destroy(String poolName){ 
        IConnectionPool pool = getPool(poolName); 
        if(pool != null){ 
            pool.destroy(); 
        } 
    } 
     
    // 获得连接池 
    public IConnectionPool getPool(String poolName){ 
        IConnectionPool pool = null; 
        if(pools.size() > 0){ 
             pool = pools.get(poolName); 
        } 
        return pool; 
    } 



package pool; 
 
import java.util.ArrayList; 
import java.util.List; 
/**
* 初始化,模拟加载所有的配置文件
* @author Ran
*
*/ 
public class DBInitInfo { 
    public  static List<DBbean>  beans = null; 
    static{ 
        beans = new ArrayList<DBbean>(); 
        // 这里数据 可以从xml 等配置文件进行获取 
        // 为了测试,这里我直接写死 
        DBbean beanOracle = new DBbean(); 
        beanOracle.setDriverName("oracle.jdbc.driver.OracleDriver"); 
        beanOracle.setUrl("jdbc:oracle:thin:@7MEXGLUY95W1Y56:1521:orcl"); 
        beanOracle.setUserName("mmsoa"); 
        beanOracle.setPassword("password1234"); 
         
        beanOracle.setMinConnections(5); 
        beanOracle.setMaxConnections(100); 
         
        beanOracle.setPoolName("testPool"); 
        beans.add(beanOracle); 
    } 



package pool; 
 
import java.sql.Connection; 
/**
* 模拟线程启动,去获得连接
* @author Ran
*
*/ 
public class ThreadConnection implements Runnable{ 
    private IConnectionPool pool; 
    @Override 
    public void run() { 
        pool = ConnectionPoolManager.getInstance().getPool("testPool"); 
    } 
     
    public Connection getConnection(){ 
        Connection conn = null; 
        if(pool != null && pool.isActive()){ 
            conn = pool.getConnection(); 
        } 
        return conn; 
    } 
     
    public Connection getCurrentConnection(){ 
        Connection conn = null; 
        if(pool != null && pool.isActive()){ 
            conn = pool.getCurrentConnecton(); 
        } 
        return conn; 
    } 



package pool; 
 
 
 
public class Client { 
    public static void main(String[] args) throws InterruptedException { 
        // 初始化连接池 
        Thread t = init(); 
        t.start(); 
        t.join(); 
         
        ThreadConnection a = new ThreadConnection(); 
        ThreadConnection b = new ThreadConnection(); 
        ThreadConnection c = new ThreadConnection(); 
        Thread t1 = new Thread(a); 
        Thread t2 = new Thread(b); 
        Thread t3 = new Thread(c); 
         
         
        // 设置优先级,先让初始化执行,模拟 线程池 先启动 
        // 这里仅仅表面控制了,因为即使t 线程先启动,也不能保证pool 初始化完成,为了简单模拟,这里先这样写了 
        t1.setPriority(10); 
        t2.setPriority(10); 
        t3.setPriority(10); 
        t1.start(); 
        t2.start(); 
        t3.start(); 
         
        System.out.println("线程A-> "+a.getConnection()); 
        System.out.println("线程B-> "+b.getConnection()); 
        System.out.println("线程C-> "+c.getConnection()); 
    } 
 
    // 初始化 
    public static Thread init() { 
        Thread t = new Thread(new Runnable() { 
            @Override 
            public void run() { 
                IConnectionPool  pool = initPool(); 
                while(pool == null || !pool.isActive()){ 
                    pool = initPool(); 
                } 
            } 
        }); 
        return t; 
    } 
     
    public static IConnectionPool initPool(){ 
        return ConnectionPoolManager.getInstance().getPool("testPool"); 
    } 
 

猜你喜欢

转载自onway417.iteye.com/blog/2223704