/*
     *  得到池空未连接数
     * * */
    public static int getNullPool(String name)
    {
        DBConnectionPool pool = (DBConnectionPool)pools.get(name);
        if (pool != null)
        {
            return pool.getNullPool();
        }else{
            return 0;
        }
    }    /*
     *  得到ORACLE 执行错误代码
     * 
     * */
    public static int getOracleErr(String name)
    {
        DBConnectionPool pool = (DBConnectionPool)pools.get(name);
        if (pool != null )
        {
            return pool.getOracleErr();
        }else{
            return 0;
        }
    }    /*
     *  释放指定连接
     * * */
    public void freeConnection(String name, Connection con)
    {
        DBConnectionPool pool = (DBConnectionPool)pools.get(name);
        if (pool != null)
        {
            pool.freeConnection(con);
        }
    }     /**
     * 获得一个可用的(空闲的)连接.如果没有可用连接
     * 且已有连接数小于最大连接数
     * 限制,则创建并返回新连接
     *
     * @param name 在属性文件中定义的连接池名字
     * @return Connection 可用连接或null
     */
    public Connection getConnection(String name)
    {
        DBConnectionPool pool = (DBConnectionPool)pools.get(name);
        if(pool != null)
        {
            return pool.getConnection();
        }
        return null;
    } 
    /*
     *  关闭连接池, 撤销驱动
     * 
     * */
    public synchronized void release()
    {
        // 有大于一个连接池管理类的实例时, 返回 
        if ( --clients != 0)
        {
            return ;
        }
        else // 只有一个连接池管理类的实例
        {
            Enumeration allPools = pools.elements();
            
            while (allPools.hasMoreElements())
            {
                DBConnectionPool pool = (DBConnectionPool)allPools.nextElement();
                pool.release();
            }
            Enumeration allDrivers = drivers.elements();
            while(allDrivers.hasMoreElements())
            {
                Driver driver = (Driver)allDrivers.nextElement();
                try{
                    DriverManager.deregisterDriver(driver);
                    log("撤销JDBC驱动程序: " + driver.getClass().getName()+"的注册");
                }catch(SQLException e){
                    log(e, "无法撤销下列JDBC驱动程序的注册 " + driver.getClass().getName());
                }
            }
        }
    } 
    /**
       * 测试指定连接池的连接情况
       */
    public static void test(String name)
    {
        DBConnectionPool pool =  (DBConnectionPool)pools.get(name);
        pool.test();
    }/**
     * 从空闲连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接
     * 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之,
     * 然后递归调用自己以尝试新的可用连接.
     */
    /**
     * 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最
     * 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性.
     */
    class DBConnectionPool
    {
        private int sum;
        private int checkedOut;
        Vector freeConnections = new Vector();
        private int maxConn; // 连接数限制
        private int max;     // 总连接数(空闲+非空闲)
        private String name;
        private String password;
        private String URL;
        private String user;
        
        // 使用getConnection没有得到连接, 返回null 的个数
    public DBConnectionPool(String name ,
                    String URL , String user, String password, int maxConn)
    {    
        this.name    = name;     // 连接池名称 
        this.URL      = URL;       // 数据库连接URL
        this.user      = user;       // 数据库用户
        this.password  = password; // 数据库密码
        this.maxConn  = maxConn;  // 最大连接数
    } 

解决方案 »

  1.   

        /**
         * 将不再使用的连接返回给连接池
         *
         * @param con 客户程序释放的连接
         */
        public synchronized void freeConnection(Connection con)
        {
            /**-----------**/
            // 测试连接的有效性, 可以去掉
            testConn(con);
            /**-----------**/
            if(con!=null)
            {
                /***----***/
                // 将指定连接加入到向量末尾
                freeConnections.addElement(con);
                /***----***/
                // 减少正在使用的连接数量
                checkedOut--;
            }
            /**-----------**/
            notifyAll();
        }
        
        public synchronized Connection getConnection()
        {
            Connection con = null;
            if(freeConnections.size() > 0)
            {
                // 获取向量中第一个可用连接
                con = (Connection)freeConnections.firstElement();
                freeConnections.removeElementAt(0);
                try{
                    if(con.isClosed())
                    {
                        log("从连接池" + name + "删除一个无效连接");
                        // 递归调用自己,尝试再次获取可用连接
                        con = getConnection();
                    }
                }catch(SQLException e) {
                    log("从连接池" + name + "删除一个无效连接");
                    // 递归调用自己,尝试再次获取可用连接
                    con = getConnection();
                }
            } else if(maxConn == 0 || checkedOut < maxConn){
                con = newConnection();
            } else  { // 大于连接数限制
        System.out.println("  连接池取空,等待回收!");
        isNullPool++ ;
       }
       
       if(con != null)
       {
        checkedOut++;
        sum++;
       }
       
       testConn(con);
       return con;
      }
      /**
       * 从连接池获取可用连接.可以指定客户程序能够等待的最长时间
       * 参见前一个getConnection()方法.
       *
       * @param timeout 以毫秒计的等待时间限制
       */
      public synchronized Connection getConnection(long timeout)
      {
       long startTime = new Date().getTime();
       Connection con;
       while( (con = getConnection()) == null)
       {
        try
        {
         wait(timeout);
        }
        catch(InterruptedException e)
        {}
        if( (new Date().getTime() - startTime) >= timeout)
        {
         // wait()返回的原因是超时
         return null;
        }
       }
       return con;
      }
      /**
       * 关闭所有连接
       */
      public synchronized void release()
      {
       Enumeration allConnections = freeConnections.elements();
       while(allConnections.hasMoreElements())
       {
        Connection con = (Connection)allConnections.nextElement();
        try
        {
         con.close();
         log("关闭连接池" + name + "中的一个连接");
        }
        catch(SQLException e)
        {
         log(e, "无法关闭连接池" + name + "中的连接");
        }
       }
       freeConnections.removeAllElements();
      }
      /**
       * 创建新的连接
       */
      private Connection newConnection()
      {
       Connection con = null;
       try
       {
        if(user == null)
        {
         con = DriverManager.getConnection(URL);
        }
        else
        {
         con = DriverManager.getConnection(URL, user, password);
        }
        /**-------------------------------------------------------------**/
        // 每建一个连接此值都将增加
        max++; 
        /**-------------------------------------------------------------**/
        log("连接池" + name + "创建一个新的连接");
       }
       catch(SQLException e)
       {
        //以下注释实在数据库连接调试正常的情况下,因为以下的情况概率最大,所以没有提示连接地址错误
        log(e, "Oracle来不及响应,无法创建下列URL的连接: " + URL);
        //System.out.println("  Oracle来不及响应!");
        isOracleErr ++ ;
        return null;
       }
       return con;
      }
      /*
       *  得到当前连接数非空闲
       * */ 
      public int getCurConns()
      {
       return checkedOut;
      }
      /*
       *  得到程序调用连接的总次数
       *  一个连接可能被调用多次
       * **/
      public int getSumConns()
      {
       return sum ;
      }
      /*
       *  得到总的连接数(空闲+非空闲)
       * ***/ 
      public int getMaxConns()
      {
       return max;
      }
      
      public int getNullPool()
      {
       return isNullPool;
      }
      public int getOracleErr()
      {
       return isOracleErr ;
      }
      public void test()
      {
       System.out.println("\r\n\r\n--------------------vect.size="+freeConnections.size()+"\r\n\r\n");
       for(int i=0;i<freeConnections.size();i++)
       {
        Connection conn = (Connection)freeConnections.get(i);
        testConn(conn);
       }
      }
      public void testConn(Connection conn)
      {
       try
       {
        if(conn.isClosed())
        {
           System.out.println("连接池错误:当前连接有问题:该连接破坏!");
        }
        Statement stm = conn.createStatement();
        ResultSet rs = stm.executeQuery("select count(*) from sms");
        
        rs.next();
        rs.close();
        stm.close();
        //System.out.println(i+"="+rs.getInt(1));
       }
       catch(SQLException s){System.out.println("连接池错误:当前连接有问题:"+s);}
      }
     }
    }