public class DBManager { private Connection con = null;
private DataSource ds = null;
private static DBManager instance = null; private DBManager() {
try {
Context context = new InitialContext();
ds = (DataSource) context.lookup("java:comp/env/ams");
} catch (NamingException e) {
System.err.println("???????命名空间异常");
e.printStackTrace();
}
} public static DBManager getInstance() {
if (instance == null)
instance = new DBManager();
return instance;
} public Connection getConnection() throws SQLException { try {
con = ds.getConnection();
con.setAutoCommit(false);
} catch (SQLException e) {
con.rollback();
System.out.println("can't get connection!");
throw e;
}
return con;
} public void close(PreparedStatement ps, ResultSet rs) {
if (con != null) {
try {
con.close();
ps.close();
rs.close();
} catch (SQLException e) {
} finally {
ps = null;
rs = null;
con = null;
}
}
} public void close(Statement st, ResultSet rs) {
if (con != null) {
try {
con.close();
st.close();
rs.close();
} catch (SQLException e) {
} finally {
st = null;
rs = null;
con = null;
}
}
} public void close(PreparedStatement ps) {
if (con != null) {
try {
con.close();
ps.close();
} catch (SQLException e) {
} finally {
ps = null;
con = null;
}
}
}
}这个数据库连接池能够连接成功,只是似乎同时只能连接两个客户端,不知道该怎么修改啊!似乎是单例出错了....有标准的通用类给我一个也行啊,谢谢了!

解决方案 »

  1.   

    我一般是用APache的DHCP的。何必自己写呢
      

  2.   

     
    private static DBManager instance = null;
    public synchronized static DBManager getInstance() {
            if (instance == null)
                instance = new DBManager();
            return instance;
        }
    }
    方法加同步,影响性能。
     方法不加同步这么写
    private static DBManager instance =new DBManager();
    public synchronized static DBManager getInstance() {
            return instance;
        
    }
      

  3.   

    写错了,第二种形式不需要synchronized 关键字
      

  4.   

    刚搞java的时候经常写这玩意,从一个类膨胀到x个类,从普通单例管理,到多线程监听,最后发现不如开源的好,呵呵。
      

  5.   

    public static DBManager getInstance() {
            if (instance == null)
              synchronized if(instance == null) {
                               instance = new DBManager();
                               return instance;
                               }
        }
    } 这样写可以吧
      

  6.   

    public static DBManager getInstance() {
           if (instance == null)
              synchronized(this) {
                 if(instance == null) {
                 instance = new DBManager();
                 return instance;
                 }
              }
           }
    }
    这样哈
      

  7.   


    /*
     * ConnectionPool.java
     *
     * Created on 2007年10月27日, 下午1:18
     *
     * To change this template, choose Tools | Template Manager
     * and open the template in the editor.
     */package connPool;
    import java.sql.Connection;
    import java.sql.DatabaseMetaData;
    import java.sql.Driver;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Vector;
    import java.util.Enumeration;
    import java.util.Iterator;/**
     *
     * @author jim
     */
    public class ConnectionPool {
        
        private volatile static ConnectionPool connPool;
        
        private String jdbcDriver="com.mysql.jdbc.Driver";   //数据库驱动
        private String dbUrl="jdbc:mysql://127.0.0.1:3306/chtx";        //数据库url
        private String dbUser="chtx";       //数据库用户
        private String dbPwd="chtx";        //数据库密码
        private String testTable="test";    //要测试的数据库表
        
        private int initConnectionSize=10; //连接池初始大小
        private int incConnectionSize=5;   //一次自增连接池大小
        private int maxConnectionSize=50;   //最大连接池大小
        
        private Vector connections=null;    //存放数据库连接对象
        
        /**
         * 构造函数<br>
         * 按默认的参数创建连接池
         */
        private ConnectionPool()
        {
        }
        
        /**
         * 构造函数
         *
         * @param jdbcDriver String 数据库驱动
         * @param dbUrl String 数据库url
         * @param dbUser String 数据库用户
         * @param dbPwd String 数据库密码
         */
        private ConnectionPool(String jdbcDriver,String dbUrl,String dbUser,String dbPwd)
        {
            this.jdbcDriver=jdbcDriver;
            this.dbUrl=dbUrl;
            this.dbUser=dbUser;
            this.dbPwd=dbPwd;
            try {
                createPool();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        
        /**
         * 生成唯一实例
         */
        public static ConnectionPool getInstance()
        {
            if(connPool == null)
            {
                synchronized (ConnectionPool.class)
                {
                    if(connPool == null)
                    {
                        connPool=new ConnectionPool();
                    }
                }
                
                try {
                    connPool.createPool();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            return connPool;
        }
        
        /**
         * 设置测试数据表
         *
         * @param testTable String 要测试的数据表
         */
        public void setTestTable(String testTable)
        {
            this.testTable=testTable;
        }
        
        /**
         * 返回测试数据表
         *
         * @return testTable String 测试数据表
         */
        public String getTestTable()
        {
            return this.testTable;
        }
        
        /**
         * 设置连接池初始大小
         *
         * @param initConnectionSize int 初始大小
         */
        public void setInitConnectionSize(int initConnectionSize)
        {
            this.incConnectionSize=initConnectionSize;
        }
        
        /**
         * 返回初始连接池大小
         *
         * @return 返回int类型
         */
        public int getInitConnectionSize()
        {
            return this.initConnectionSize;
        }
        
        /**
         * 设置连接池一次性自增数大小
         *
         * @param incConnectionSize int 自增数
         */
        public void setIncConnectionSize(int incConnectionSize)
        {
            this.incConnectionSize=incConnectionSize;
        }
        
        /**
         * 返回连接池一次性自增数大小
         *
         * @return 返回int类型
         */
        public int getIncConnectionSize()
        {
            return this.incConnectionSize;
        }
        
        /**
         * 设置最大连接池大小
         *
         * @param maxConnectionSize int 最大连接池大小
         */
        public void setMaxConnectionSize(int maxConnectionSize)
        {
            this.maxConnectionSize=maxConnectionSize;
        }
        
        /**
         * 返回最大连接池大小
         * 
         * @return 返回int类型
         */
        public int getMaxConnectionSize()
        {
            return this.maxConnectionSize;
        }
        
        /**
         * 关闭数据库连接对象
         *
         * @param conn Connection 数据库连接对象
         */
        public void closeConnection(Connection conn)
        {
            try {
                conn.close();
                System.out.println("The connection is close ...");
            } catch (SQLException ex) {
                System.out.println("Close failure of the database connection object ...");
                conn=null;
                ex.printStackTrace();
            }
        }
        
        /**
         * 测试连接池中的连接对象是否可用
         * false不可用销毁该连接,true可用
         *
         * @param conn Connection 数据库连接对象
         * @return boolean
         */
        public boolean testConnection(Connection conn)
        {
            try {
                //是否有测试表,提供测试
                if(testTable.equals(""))
                {
                    conn.setAutoCommit(true);
                }
                else
                {
                    Statement stmt=conn.createStatement();
                    stmt.execute("select count(*) from " + testTable);
                }
            } catch (SQLException ex) {
                closeConnection(conn);
                System.out.println("The database connection object can't be used, in the close ...");
                ex.printStackTrace();
                return false;
            }
            
            return true;
        }
        
        /**
         * 获取空闲的数据库连接对象
         *
         * @return Connection
         */
        public Connection getConnection()
        throws SQLException
        {
            //还没创建连接池
            if(connections==null)
                return null;
            
            Connection conn=getFreeConnection();
            
            //拿不到数据库连接对象就一直试
            while(conn==null)
            {
                wait(250);
                conn=getFreeConnection();
            }
            
            return conn;
        }
        
        /**
         * 让程序停止 ? 毫秒
         * 
         * @param ms int 毫秒
         */
        private void wait(int ms)
        {
            try {
                Thread.sleep(ms);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    我自己写的数据库连接池,
      

  8.   

        
        /**
         * 获取可用连接,如果没有可用连接,则创建一定量(incConnection)的连接数,
         * 如果在没有获取到可用连接,则直接返回null
         *
         * @return Connection
         */
        private Connection getFreeConnection()
        throws SQLException
        {
            Connection conn=findFreeConnection();
            
            if(conn==null)
            {
                createConnections(this.incConnectionSize);
                conn=findFreeConnection();
                
                //如果还是没办法获取空闲连接数,则返回null
                if(conn==null)
                    return null;
            }
            
            return conn;
        }
        
        /**
         * 查找空闲的数据库连接对象
         *
         * @return Connection
         */
        private Connection findFreeConnection()
        {
            Connection conn=null;
            PooledConnection pConn=null;
            
            Enumeration enumeration=connections.elements();
            
            while(enumeration.hasMoreElements())
            {
                pConn=(PooledConnection)enumeration.nextElement();
                //如果不繁忙则获取连接对象
                if(!pConn.isBusy())
                {
                    conn=pConn.getConnection();
                    if(!testConnection(conn))
                    {
                        try {
                            conn=createNewConnection();
                        } catch (SQLException ex) {
                            System.out.println("Create the database connection object failed:"+ex.getMessage());
                            ex.printStackTrace();
                            return null;
                        }
                        pConn.setConnection(conn);
                    }
                    pConn.setBusy(true);
                    break;
                }
            }
            
            return conn;
        }
        
        /**
         * 回收connection对象
         */
        public void returnConnection(Connection conn)
        {
            if(connections==null)
            {
                System.out.println("The database connection pool wasn't created ...");
                return ;
            }
            
            Enumeration enumeration=connections.elements();
            PooledConnection pConn=null;
            
            while(enumeration.hasMoreElements())
            {
                pConn=(PooledConnection)enumeration.nextElement();
                if(pConn.getConnection()==conn)
                {
                    pConn.setBusy(false);
                    break;
                }
            }
        }
        
        /**
         * 刷新连接池
         */
        public synchronized void refreshPool()
        throws SQLException
        {
            if(connections==null)
            {
                System.out.println("The database connection pool wasn't created ...");
                return ;
            }
            
            PooledConnection pConn=null;
            Enumeration enumeration=connections.elements();
            
            while(enumeration.hasMoreElements())
            {
                pConn=(PooledConnection)enumeration.nextElement();
                if(pConn.isBusy())
                {
                    wait(5000);
                }
                
                closeConnection(pConn.getConnection());
                pConn.setConnection(createNewConnection());
                pConn.setBusy(false);
            }
            
        }
        
        /**
         * 关闭连接池
         */
        public synchronized void closePool()
        {
            if(connections==null)
            {
                System.out.println("The database connection pool wasn't created ...");
                return ;
            }
            
            PooledConnection pConn=null;
            
            Iterator it=connections.iterator();
            int i=1;
            while(it.hasNext())
            {
                
                pConn=(PooledConnection)(it.next());
                
                if(pConn.isBusy())
                {
                    wait(5000);
                }
                
                closeConnection(pConn.getConnection());
            }
            connections.clear();
            connections=null;
        }
      

  9.   


        
        /**
         * 创建数据库连接池
         */
        public synchronized void createPool()
        throws Exception
        {
            //防止多次创建
            if(connections!=null)
                return ;
            
            //实例化驱动
            Driver driver=(Driver)(Class.forName(jdbcDriver).newInstance());
            DriverManager.registerDriver(driver);
            
            //创建Connection对象容器
            connections=new Vector();
            
            //初始化连接池
            createConnections(this.initConnectionSize);
            
            System.out.println("Create the database connection pool with success ...");
        }
        
        /**
         * 创建指定数目的Connection对象
         *
         * @param count int 要创建Connection对象的个数
         */
        private void createConnections(int count)
        throws SQLException
        {
            for(int i=0;i<count;i++)
            {
                if(maxConnectionSize>0 && connections.size()>=maxConnectionSize)
                {
                    System.out.println("The database connection has attained the maximum connection, can't be created ...");
                    break;
                }
                
                try 
                {    
                    connections.addElement(new PooledConnection(createNewConnection()));
                } catch (SQLException ex) {
                    System.out.println("Create the database connection object failed ....");
                    System.out.println(ex.getMessage());
                    throw new SQLException();
                }
                
                System.out.println("Create the database connection object with success ...");
            } 
        }
        
        
        /**
         * 创建一个新的Connection
         * @return 返回一个新的Connection对象
         */
        private Connection createNewConnection()
        throws SQLException
        {
            Connection conn=DriverManager.getConnection(dbUrl,dbUser,dbPwd);
            
            //如果是第一次创建
            if(connections.size()==0)
            {
                DatabaseMetaData metaData=conn.getMetaData();
                int maxConnections=metaData.getMaxConnections();
                
                //如果数据库连接池数超出数据库的连接数,则设置数据库的连接数
                if(maxConnectionSize> maxConnections)
                {
                    maxConnectionSize=maxConnections;
                }
                
            }
            return conn;
        }
        
    /* --------------------|inner class PooledConnection|-------------------- */
        /**
         * 创建connection对象,并且可查询connection状态
         */
        class PooledConnection
        {
            
            private boolean busy=false;
            private Connection conn=null;
            private int count=0;
            
            /**
             * 构造函数
             *
             * @param conn Connection connection对象
             */
            public PooledConnection(Connection conn)
            {
                this.conn=conn;
            }//`
            
            /**
             * 设置connection对象
             *
             * @param conn Connection connection对象
             */
            public void setConnection(Connection conn)
            {
                this.conn=conn;
            }
            
            /**
             * 返回connection对象
             *
             * @return 返回connection对象
             */
            public Connection getConnection()
            {
                return this.conn;
            }
            
            /**
             * 设置数据库状态
             *
             * @param busy boolean false空闲,true繁忙
             */
            public void setBusy(boolean busy)
            {
                this.busy=busy;
                if(this.busy)
                {
                    count++;
                }else
                {
                    if(count == 1000)
                    {
                        try {
                            if(conn != null)
                            {
                                conn.close();
                                conn = null;
                                conn = createNewConnection();
                                count = 0;
                                System.out.println("conn auto close");
                            }
                        } catch (SQLException ex) {
                            Log.exception(log, ex, Level.WARNING);
                        }
                    }
                }
            }
            
            /**
             * 返回数据库状态
             * 
             * @return false空闲,true繁忙
             */
            public boolean isBusy()
            {
                return this.busy;
            }
            
        }//class~
        /* --------------------|inner class PooledConnection|-------------------- */
        
    }//class~
      

  10.   

    ==================================
    package com.east.db;import javax.sql.DataSource;
    import javax.naming.InitialContext;
    import javax.naming.Context;
    import java.sql.*;
    public class DBTools {
      public static Connection getCon(){
      Connection con = null;
      try{
      Context ctx = new  InitialContext();
      DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/ds");
      if (ds != null){
      con = ds.getConnection();
      }
      }
      catch(Exception se){
      se.printStackTrace();
      }finally{
      return con;
      }
      }
    }
    ----web.xml--------------------------------------------
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4" 
    xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">    <resource-ref>
          <description>sqlserverDB connection</description>
          <res-ref-name>jdbc/ds</res-ref-name>
          <res-type>javax.sql.DataSource</res-type>
          <res-auth>Container</res-auth>
      </resource-ref>
    </web-app>
    ---tomcat servlet.xml--------------------------------        <!--
            <Valve className="org.apache.catalina.valves.FastCommonAccessLogValve"
                     directory="logs"  prefix="localhost_access_log." suffix=".txt"
                     pattern="common" resolveHosts="false"/>
            -->
    <Context path="/Pool" docBase="Pool" debug="1" reloadable="true">   
    <Resource name="jdbc/ds" auth="Container" type="javax.sql.DataSource"  
    driverClassName="com.microsoft.jdbc.sqlserver.SQLServerDriver"
    url="jdbc:microsoft:sqlserver://localhost:1433;databasename=pubs"  
    username="sa" password=""  
    maxWait="5000" maxActive="4"  
    maxIdle="4"/>   
    </Context>       </Host>    </Engine>  </Service></Server>