`

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"); 
    } 
 
分享到:
评论

相关推荐

    JAVA 完整的数据库连接池实现

    本文将详细介绍如何在 Java 中实现一个完整的数据库连接池,并探讨其核心概念、工作原理以及如何根据需求进行配置。 首先,我们需要理解数据库连接池的基本概念。数据库连接池是一种对象池设计模式的应用,它维护了...

    Java jdbc数据库连接池总结

    Java JDBC 数据库连接池总结 Java 语言中,JDBC(Java DataBase Connection)是应用程序与数据库沟通的桥梁。在 Web 应用开发的早期,主要使用的技术是 CGIASPPHP 等。之后,Sun 公司推出了基于 Java 语言的 ...

    java数据库连接池

    描述:本篇将详细介绍Java数据库连接池的概念,代码实现以及其在实际项目中的应用。数据库连接池是Java开发中优化数据库访问效率的关键技术,通过复用预创建的数据库连接,避免频繁创建和销毁连接带来的性能开销。 ...

    JAVA数据库连接池

    Java数据库连接池是Java开发中一个非常重要的技术,它主要用于管理数据库连接,提高数据库操作的效率和性能。在Java应用程序中,频繁地创建和关闭数据库连接会导致大量的系统资源浪费,而连接池则可以复用已建立的...

    JAVA数据库连接池类

    本篇文章将深入解析一个自定义的JAVA数据库连接池类,帮助开发者更好地理解和运用这一关键技术。 首先,连接池的基本思想是预先创建一定数量的数据库连接,并存储在一个集合(如Vector)中,供应用程序按需获取和...

    JAVA 使用数据库连接池连接Oracle数据库全代码

    ### JAVA 使用数据库连接池连接Oracle数据库全代码解析 #### 一、概述 本文将详细介绍如何在Java项目中使用Apache DBCP(Database Connection Pool)来连接Oracle数据库,并提供完整的示例代码。通过这种方式,我们...

    轻量级java数据库连接池

    本项目提供了一个轻量级的Java数据库连接池实现,旨在简化开发过程,提高应用性能并降低资源消耗。下面将详细介绍这个轻量级Java数据库连接池的设计理念、工作原理以及如何使用。 1. **设计理念** 轻量级数据库...

    java数据库连接池.rar

    总的来说,Java数据库连接池如C3P0和Druid,以及Spring的JdbcTemplate,都是为了优化数据库操作而设计的工具。它们各自有其特点和优势,开发者可以根据项目需求选择合适的技术。在使用过程中,充分理解和合理配置...

    Java数据库连接池的使用示例

    Java数据库连接池是Java应用程序管理数据库连接的一种高效方式。它避免了每次需要访问数据库时创建新的连接,而是预先创建一定数量的连接并保存在池中,当程序需要时可以从池中获取,用完后归还,从而提高了系统性能...

    Java数据库连接池的原理与应用.pdf

    Java数据库连接池的原理与应用 在Java开发领域,数据库连接池(Database Connection Pool,简称DBCP)是一种提高数据库访问性能、降低资源消耗的重要技术。它通过预先建立一定数量的数据库连接,存储在一个“池”中...

    数据库连接池java代码实现

    数据库连接池在Java中的实现是提高应用程序性能的关键技术之一,它通过复用已存在的数据库连接,避免了频繁创建和销毁连接导致的系统资源浪费。本文将深入探讨如何使用Java代码来实现一个简单的数据库连接池,并解释...

Global site tag (gtag.js) - Google Analytics