期待高手予以解决!我利用java数据库连接池来实现多线程连接mysql数据库。
代码如下:希望高手耐心看完:Pool.java代码:
package demo;/*
我的数据库连接池***********模块说明**************getInstance()返回POOL唯一实例,第一次调用时将执行构造函数
构造函数Pool()调用驱动装载loadDrivers()函数;连接池创建createPool()函数
loadDrivers()装载驱动
createPool()建连接池
getConnection()返回一个连接实例
getConnection(long time)添加时间限制
freeConnection(Connection con)将con连接实例返回到连接池
getnum()返回空闲连接数
getnumActive()返回当前使用的连接数*/import java.sql.*;public class Pool {static private Pool instance = null; //定义唯一实例private int maxConnect = 20;//最大连接数
private int normalConnect = 10;//保持连接数
private String password = "wlxu_07";//密码
private String url = "jdbc:mysql://localhost/tickets";//连接URL
private String user = "root";//用户名
private String driverName = "com.mysql.jdbc.Driver";//驱动类
Driver driver = null;//驱动变量
DBConnectionPool pool = null;//连接池实例变量//返回唯一实例
static synchronized public Pool getInstance() {
    if (instance == null) {
      instance = new Pool();
    }    return instance;
}//将构造函数私有,不允许外界访问
private Pool() {
    loadDrivers(driverName);
    createPool();}//装载和注册所有JDBC驱动程序
private void loadDrivers(String dri) {    String driverClassName = dri;
    try {
      driver = (Driver) Class.forName(driverClassName).newInstance();
      DriverManager.registerDriver(driver);
      System.out.println("成功注册JDBC驱动程序" + driverClassName);
    }
    catch (Exception e) {
      System.out.println("无法注册JDBC驱动程序:" + driverClassName + ",错误:" + e);
    }
}//创建连接池
private void createPool() {
    pool = new DBConnectionPool(password, url, user, normalConnect, maxConnect);
    if (pool != null) {
      System.out.println("创建连接池成功");
    }
    else {
      System.out.println("创建连接池失败");
    }
}//获得一个可用的连接,如果没有则创建一个连接,且小于最大连接限制
public Connection getConnection() throws InterruptedException {
    if (pool != null) {
      return pool.getConnection();
    }
    return null;
}//获得一个连接,有时间限制
public Connection getConnection(long time) throws InterruptedException {
    if (pool != null) {
      return pool.getConnection(time);
    }
    return null;
}//将连接对象返回给连接池
public void freeConnection(Connection con) {
    if (pool != null) {
      pool.freeConnection(con);
    }
}//返回当前空闲连接数
public int getnum()
{
    return pool.getnum();
}
//返回当前连接数
public int getnumActive()
{
    return pool.getnumActive();
}
//关闭所有连接,撤销驱动注册
public synchronized void release() {    ///关闭连接
    pool.release();    ///撤销驱动
    try {
      DriverManager.deregisterDriver(driver);
      System.out.println("撤销JDBC驱动程序 " + driver.getClass().getName());
    }
    catch (SQLException e) {
      System.out.println("无法撤销JDBC驱动程序的注册:" + driver.getClass().getName());
    }}}DBConnectionPool.java文件:package demo;import java.sql.*;
import java.util.*;
import java.util.Date;
public class DBConnectionPool {
private int checkedOut;
private Vector freeConnections = new Vector();
private int maxConn;
private int normalConn;
private String password;
private String url;
private String user;
private static int num=0;//空闲的连接数
private static int numActive=0;//当前的连接数public DBConnectionPool(String password, String url, String user,
                          int normalConn, int maxConn) {
    this.password = password;
    this.url = url;
    this.user = user;
    this.maxConn = maxConn;
    this.normalConn = normalConn;    for (int i = 0; i < normalConn; i++) { //初始normalConn个连接
      Connection c = newConnection();
      if (c != null)
        {freeConnections.addElement(c);num++;}
    }
}//释放不用的连接到连接池
public synchronized void freeConnection(Connection con) {
    freeConnections.addElement(con);
    num++;
    checkedOut--;
    numActive--;
    notifyAll();
}//获取一个可用连接
public synchronized Connection getConnection() throws InterruptedException {
    Connection con = null;    if (freeConnections.size() > 0) { //还有空闲的连接
      num--;      con = (Connection) freeConnections.firstElement();
      freeConnections.removeElementAt(0);
      try {
        if (con.isClosed()) {
          System.out.println("从连接池删除一个无效连接");
          con = getConnection();
        }
      }
      catch (SQLException e) {
        System.out.println("从连接池删除一个无效连接");
        con = getConnection();
      }
    }    else if (maxConn == 0 || checkedOut < maxConn) { //没有空闲连接且当前连接小于最大允许值,最大值为0则不限制
      con = newConnection();
    }
    
    else
    {
        Thread.sleep(1000);
        getConnection();
    }
    if (con != null) { //当前连接数加1
      checkedOut++;
    }    numActive++;
    return con;}//获取一个连接,并加上等待时间限制,时间为毫秒
public synchronized Connection getConnection(long timeout) throws InterruptedException {
    long startTime = new Date().getTime();
    Connection con;
    while ( (con = getConnection()) == null) {      try {
        wait(timeout);
      }
      catch (InterruptedException e) {}      if ( (new Date().getTime() - startTime) >= timeout) {
        return null; //超时返回
      }
    }
    return con;
}//关闭所有连接
public synchronized void release() {
    Enumeration allConnections = freeConnections.elements();
    while (allConnections.hasMoreElements()) {
      Connection con = (Connection) allConnections.nextElement();
      try {
        con.close();
        num--;
      }
      catch (SQLException e) {
        System.out.println("无法关闭连接池中的连接");
      }
    }
    freeConnections.removeAllElements();
    numActive=0;
}//创建一个新连接
private Connection newConnection() {
    Connection con = null;
    try {
      if (user == null) { //用户,密码都为空
        con = DriverManager.getConnection(url);
      }
      else {
        con = DriverManager.getConnection(url, user, password);
      }
      System.out.println("连接池创建一个新的连接");
    }
    catch (SQLException e) {
      System.out.println("无法创建这个URL的连接" + url);
      return null;
    }
    return con;
}
//返回当前空闲连接数
public int getnum()
{
    return num;
}
//返回当前连接数
public int getnumActive()
{
    return numActive;
}
}然后我在调用连接池是,可以取出20个conn线程。
确没有执行freeConnection释放线程函数,为什么啊??

解决方案 »

  1.   

    我稍微看了下,LZ你那里的代码:是public void freeConnection(Connection con) {
        if (pool != null) {
          pool.freeConnection(con);
        }
    }当你创建了20个线程时,你的线程池空了那么你的判断语句就导致你无法释放了。
      

  2.   

    没必要这么写吧,直接用Mysql的就行了。
      

  3.   

    应该不是这两个类的问题,而是你什么时候调用Conn的close方法,以及Conn的close方法是如何实现的
      

  4.   


    我是在整个连接mysql程序运行我拿了才把线程池里面的conn关闭。这样能避免重复创建conn。
      

  5.   

    参考一下DBCP吧, 你的很多配置参数他们也有。  http://commons.apache.org/dbcp/  
    ---------------------------
    细粒度权限管理软件 试用版下载
    www.metadmin.com
      

  6.   

    Pool 和 DBConnectionPool 两个类不能合一起写么?
      

  7.   

    给你推荐一篇文章
    http://www.ibm.com/developerworks/cn/java/l-connpoolproxy/
      

  8.   

    我觉得你实现的连接池,要想关闭conn得调用freeConnection方法,你是这样调用的吗?
      

  9.   

    如果想要调用conn.Close方法关闭,连接池就得做成16楼帖子中所说的动态代理
    其中Connection的代理类的实现见如下链接:
    http://www.builder.com.cn/2008/0509/852122.shtml
      

  10.   

    貌似楼主的freeConnection()这个方法里 并没有关闭Connection啊...
      

  11.   

    建议楼主使用DBCP连接池,具体的可以参考下:
    http://blog.csdn.net/johnston678/archive/2009/06/06/4247915.aspx
    现在已经有现在的连接池了,自己实现的功能肯定没有现在的产品好!
      

  12.   

    调用freeConnection()方法把连接放回连接池里
    连接的真正关闭由连接池控制
      

  13.   

    为什么不直接用apache的连接池 下载commons-pool-1.4.jar和commons-dbcp-1.2.2.jar