java实现数据库连接池

package nju.iip.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import nju.iip.util.Config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**

  • 连接池类
  • @author wangqiang

*/
public class ConnectionPool {

</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> Logger logger = LoggerFactory.getLogger(ConnectionPool.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">);

</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> max_connection = Integer.valueOf(Config.getValue("max_connection"));<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 最大连接数</span>

<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> min_connection = Integer.valueOf(Config.getValue("min_connection"));<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 最小连接数</span>

<span style="color: rgba(0, 0, 255, 1)">private</span> Map&lt;Connection,String&gt; connection_map;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 存放连接池的容器</span>

<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> ConnectionPool connectPool;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 单例</span>

<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> waitTime = 100<span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> ConnectionPool() {
    logger.info(</span>"创建连接池...."<span style="color: rgba(0, 0, 0, 1)">);
    intializePool();
    logger.info(</span>"创建连接池成功....共"+connection_map.size()+"个连接"<span style="color: rgba(0, 0, 0, 1)">);
}

</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
 * 获取连接池单例
 * 
 * </span><span style="color: rgba(128, 128, 128, 1)">@return</span><span style="color: rgba(0, 128, 0, 1)"> connectPool
 </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> ConnectionPool getInstance() {
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (connectPool == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
        </span><span style="color: rgba(0, 0, 255, 1)">synchronized</span> (ConnectionPool.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">) {
            </span><span style="color: rgba(0, 0, 255, 1)">if</span> (connectPool == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
                connectPool </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ConnectionPool();
            }
        }
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> connectPool;
}

</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> intializePool() {
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (connection_map != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
        </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
    }
    connection_map </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> ConcurrentHashMap&lt;Connection,String&gt;<span style="color: rgba(0, 0, 0, 1)">();
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
        </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i &lt; min_connection; i++<span style="color: rgba(0, 0, 0, 1)">) {
            connection_map.put(getNewConnection(),</span>"free"<span style="color: rgba(0, 0, 0, 1)">);
        }
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
        logger.info(</span>"intializePool error"<span style="color: rgba(0, 0, 0, 1)">, e);
    }
}

</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Connection getNewConnection() {
    Connection conn </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
        Class.forName(Config.getValue(</span>"DBDRIVER"<span style="color: rgba(0, 0, 0, 1)">));
        conn </span>= DriverManager.getConnection(Config.getValue("DBURL"), Config.getValue("DBUSER"),Config.getValue("DBPASSWORD"<span style="color: rgba(0, 0, 0, 1)">));
    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
        logger.info(</span>"getNewConnection error"<span style="color: rgba(0, 0, 0, 1)">, e);
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> conn;
}

</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
 * 获取一个连接
 * </span><span style="color: rgba(128, 128, 128, 1)">@return</span>
 <span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)">  Connection getConnection() {
    Connection conn </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> (Entry&lt;Connection, String&gt;<span style="color: rgba(0, 0, 0, 1)"> entry : connection_map.entrySet()) {
        </span><span style="color: rgba(0, 0, 255, 1)">if</span> (entry.getValue().equals("free"<span style="color: rgba(0, 0, 0, 1)">)) {
            conn </span>=<span style="color: rgba(0, 0, 0, 1)"> entry.getKey();
            connection_map.put(conn,</span>"busy"<span style="color: rgba(0, 0, 0, 1)">);
            </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
        }
    }
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (conn == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
        </span><span style="color: rgba(0, 0, 255, 1)">if</span> (connection_map.size() &lt;<span style="color: rgba(0, 0, 0, 1)">max_connection) {
            conn </span>= getNewConnection();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">新建一个连接</span>
            connection_map.put(conn,"busy"<span style="color: rgba(0, 0, 0, 1)">);
            logger.info(</span>"no free connection,add new connection ok!"<span style="color: rgba(0, 0, 0, 1)">);
        } 
        </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
            logger.info(</span>"reach max_connction!start watting..."<span style="color: rgba(0, 0, 0, 1)">);
            wait(waitTime);
            conn </span>=<span style="color: rgba(0, 0, 0, 1)"> getConnection();
        }
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> conn;
}


</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
 * 释放连接
 * </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> myconnection
 </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">synchronized</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> releaseConnection(Connection conn) {
    </span><span style="color: rgba(0, 0, 255, 1)">if</span>(conn == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
        </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
    }
     </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">{
         </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(connection_map.containsKey(conn)) {
             </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(conn.isClosed()) {
                 connection_map.remove(connectPool);
             }
             </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
                 connection_map.put(conn,</span>"free"<span style="color: rgba(0, 0, 0, 1)">);   
                 logger.info(</span>"releaseConnection ok..."<span style="color: rgba(0, 0, 0, 1)">);
             }
         } 
         </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
             conn.close();
         }
     }</span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)">(Exception e){
         logger.info(</span>"releaseConnection error"<span style="color: rgba(0, 0, 0, 1)">, e);
     }
 }

</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> wait(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> waitTime) {
    </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">{
        Thread.sleep(waitTime);
    }</span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)">(Exception e){
        logger.info(</span>"wait error"<span style="color: rgba(0, 0, 0, 1)">, e);
    }
}</span><span style="color: rgba(0, 0, 0, 1)">

}